{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Ch 9 Multi-Agent Reinforcement Learning"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import torch\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "def init_grid(size=(10,)):\n",
    "    grid = torch.randn(*size)\n",
    "    grid[grid > 0] = 1\n",
    "    grid[grid <= 0] = 0\n",
    "    grid = grid.byte() #A\n",
    "    return grid\n",
    "\n",
    "def get_reward(s,a): #B\n",
    "    r = -1\n",
    "    for i in s:\n",
    "        if i == a:\n",
    "            r += 0.9\n",
    "    r *= 2.\n",
    "    return r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gen_params(N,size): #A\n",
    "    ret = []\n",
    "    for i in range(N):\n",
    "        vec = torch.randn(size) / 10.\n",
    "        vec.requires_grad = True\n",
    "        ret.append(vec)\n",
    "    return ret\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def qfunc(s,theta,layers=[(4,20),(20,2)],afn=torch.tanh):\n",
    "    l1n = layers[0] \n",
    "    l1s = np.prod(l1n) #A\n",
    "    theta_1 = theta[0:l1s].reshape(l1n) #B\n",
    "    l2n = layers[1]\n",
    "    l2s = np.prod(l2n)\n",
    "    theta_2 = theta[l1s:l2s+l1s].reshape(l2n)\n",
    "    bias = torch.ones((1,theta_1.shape[1]))\n",
    "    l1 = s @ theta_1 + bias #C\n",
    "    l1 = torch.nn.functional.elu(l1)\n",
    "    l2 = afn(l1 @ theta_2) #D\n",
    "    return l2.flatten()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_substate(b): #A\n",
    "    s = torch.zeros(2) \n",
    "    if b > 0: #B\n",
    "        s[1] = 1\n",
    "    else:\n",
    "        s[0] = 1\n",
    "    return s\n",
    "\n",
    "def joint_state(s): #C\n",
    "    s1_ = get_substate(s[0]) #D\n",
    "    s2_ = get_substate(s[1])\n",
    "    ret = (s1_.reshape(2,1) @ s2_.reshape(1,2)).flatten() #E\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n",
      "       dtype=torch.uint8)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7f72a7d04c70>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,5))\n",
    "size = (20,) #A\n",
    "hid_layer = 20 #B\n",
    "params = gen_params(size[0],4*hid_layer+hid_layer*2) #C\n",
    "grid = init_grid(size=size)\n",
    "grid_ = grid.clone() #D\n",
    "print(grid)\n",
    "plt.imshow(np.expand_dims(grid,0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "epochs = 200\n",
    "lr = 0.001 #A\n",
    "losses = [[] for i in range(size[0])] #B\n",
    "for i in range(epochs):\n",
    "    for j in range(size[0]): #C\n",
    "        l = j - 1 if j - 1 >= 0 else size[0]-1 #D\n",
    "        r = j + 1 if j + 1 < size[0] else 0 #E\n",
    "        state_ = grid[[l,r]] #F\n",
    "        state = joint_state(state_) #G\n",
    "        qvals = qfunc(state.float().detach(),params[j],layers=[(4,hid_layer),(hid_layer,2)])\n",
    "        qmax = torch.argmax(qvals,dim=0).detach().item() #H\n",
    "        action = int(qmax)\n",
    "        grid_[j] = action #I\n",
    "        reward = get_reward(state_.detach(),action)\n",
    "        with torch.no_grad(): #J\n",
    "            target = qvals.clone()\n",
    "            target[action] = reward\n",
    "        loss = torch.sum(torch.pow(qvals - target,2))\n",
    "        losses[j].append(loss.detach().numpy())\n",
    "        loss.backward()\n",
    "        with torch.no_grad(): #K\n",
    "            params[j] = params[j] - lr * params[j].grad\n",
    "        params[j].requires_grad = True\n",
    "    with torch.no_grad(): #L\n",
    "        grid.data = grid_.data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Visualization of 1D Ising Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0],\n",
      "       dtype=torch.uint8) tensor(5)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7f72a7dfd990>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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rLPOEg8++KAwm829W3GFrr76apGZmSl0Op0YMGCAuPrqq8WRI0fc+5uamsSdd94pEhMTRXR0tPif//kfUVpa2os17pxVq1YJAKKoqMhje6Tev/Xr13v9e3njjTcKIVqGSz/yyCMiPT1d6PV6MX369A7XXl1dLa699loRGxsr4uPjxc033ywsFksvXE1H/q6vuLjY58/l+vXrhRBC7NixQ+Tn5wuj0SgMBoMYNWqUeOqppzw++Hubv2tsbGwUM2bMEKmpqUKr1YqcnBxx2223dfhHYDjfQyEC/z0VQohXXnlFREVFCZPJ1OH4cL+PgT4fhFD2O/TYsWNi9uzZIioqSqSkpIgHHnhA2O32kNVTaq0sERERUURgnxciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIkq3hZeamhrMmzcP8fHxSEhIwPz581FfX+/3mAsvvBCSJHl8/eEPf+iuKhIREVEEkoQQojtOPHv2bJSW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e22z2fD222/jlltu8buyel+4120VFxejrKzM434ajUbk5+f7vJ+d+f0QCcxmMyRJCrhIbTA/K+Fqw4YNSEtLw4gRI3DHHXegurraZ9m+eL/Ly8vx5ZdfYv78+QHL9oX77dLnw0tVVRWcTifS09M9tqenp6OsrMzrMWVlZUGVD3eyLOO+++7Deeedh7y8PJ/lRowYgddffx2ffvop3n77bciyjGnTpuHkyZM9WNuuyc/Px5tvvomVK1dixYoVKC4uxi9/+UtYLBav5fvavQaATz75BCaTCTfddJPPMn3hXrfnumfB3M/O/H4Id83NzVi0aBGuvfZav6sLB/uzEo5mzZqFf//731i7di2eeeYZbNy4EbNnz4bT6fRavi/e77feegtxcXG44oor/JbrC/e7rW5f24h634IFC7Bv376AzzenTp3qsWDmtGnTMGrUKLzyyit48sknu7uaITF79mz3/48bNw75+fnIycnBhx9+qOhfJn3Ba6+9htmzZyMrK8tnmb5wr6kju92Oq666CkIIrFixwm/ZvvCzcs0117j/f+zYsRg3bhyGDh2KDRs2YPr06b1Ys57z+uuvY968eQE73PeF+91Wn295SUlJgVqtRnl5ucf28vJyZGRkeD0mIyMjqPLh7K677sIXX3yB9evXY+DAgUEdq9Vqcc455+DIkSPdVLvul5CQgOHDh/u8hr50rwGgpKQEa9asCXoh075wr133LJj72ZnfD+HKFVxKSkqwevVqv60u3gT6WYkEQ4YMQUpKis9r6Ev3GwC+++47FBUVdWrh4ki/330+vOh0OkycOBFr1651b5NlGWvXrvX4l2dbU6dO9SgPAKtXr/ZZPhwJIXDXXXfh448/xrp165Cbmxv0OZxOJ/bu3YvMzMxuqGHPqK+vx9GjR31eQ1+412298cYbSEtLw5w5c4I6ri/c69zcXGRkZHjcz7q6OmzdutXn/ezM74dw5Aouhw8fxpo1a5CcnBz0OQL9rESCkydPorq62uc19JX77fLaa69h4sSJGD9+fNDHRvz97u0ewz3h/fffF3q9Xrz55pviwIED4vbbbxcJCQmirKxMCCHE7373O/HQQw+5y2/atEloNBrx17/+VRw8eFAsWbJEaLVasXfv3t66hKDdcccdwmg0ig0bNojS0lL3V2Njo7tM++t+/PHHxapVq8TRo0fFjh07xDXXXCMMBoPYv39/b1xCpzzwwANiw4YNori4WGzatEkUFBSIlJQUUVFRIYTom/faxel0ikGDBolFixZ12NdX7rXFYhG7du0Su3btEgDEc889J3bt2uUeVfP000+LhIQE8emnn4o9e/aIyy+/XOTm5oqmpib3OX7961+LF154wf060O+HcODvum02m7jsssvEwIEDxe7duz1+3q1Wq/sc7a870M9KOPB33RaLRfzxj38UhYWFori4WKxZs0ZMmDBBDBs2TDQ3N7vP0dfut4vZbBbR0dFixYoVXs8Rifc7GP0ivAghxAsvvCAGDRokdDqdmDJlitiyZYt73wUXXCBuvPFGj/IffvihGD58uNDpdGLMmDHiyy+/7OEadw0Ar19vvPGGu0z7677vvvvc36P09HRx8cUXi507d/Z85bvg6quvFpmZmUKn04kBAwaIq6++Whw5csS9vy/ea5dVq1YJAKKoqKjDvr5yr9evX+/177Xr2mRZFo888ohIT08Xer1eTJ8+vcP3IycnRyxZssRjm7/fD+HA33UXFxf7/Hlfv369+xztrzvQz0o48HfdjY2NYsaMGSI1NVVotVqRk5Mjbrvttg4hpK/db5dXXnlFREVFCZPJ5PUckXi/gyEJIUS3Nu0QERERhVCf7/NCREREfQvDCxEREUUUhhciIiKKKAwvREREFFEYXoiIiCiiMLwQERFRRGF4ISIioojC8EJEREQRheGFiIiIIgrDCxEREUUUhhciIiKKKP8/khc/FlCZoesAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig,ax = plt.subplots(2,1)\n",
    "for i in range(size[0]):\n",
    "    ax[0].scatter(np.arange(len(losses[i])),losses[i])\n",
    "print(grid,grid.sum())\n",
    "ax[1].imshow(np.expand_dims(grid,0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.9"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import deque #A\n",
    "from random import shuffle #B\n",
    "\n",
    "def softmax_policy(qvals,temp=0.9): #C\n",
    "    soft = torch.exp(qvals/temp) / torch.sum(torch.exp(qvals/temp)) #D\n",
    "    action = torch.multinomial(soft,1) #E\n",
    "    return action"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_coords(grid,j): #A\n",
    "    x = int(np.floor(j / grid.shape[0])) #B\n",
    "    y = int(j - x * grid.shape[0]) #C\n",
    "    return x,y\n",
    "\n",
    "def get_reward_2d(action,action_mean): #D\n",
    "    r = (action*(action_mean-action/2)).sum()/action.sum() #E\n",
    "    return torch.tanh(5 * r) #F"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(-0.8483) tensor(0.8483)\n"
     ]
    }
   ],
   "source": [
    "x1 = get_reward_2d(torch.Tensor([1,0]),torch.Tensor([0.25, 0.75]))\n",
    "x2 = get_reward_2d(torch.Tensor([0,1]),torch.Tensor([0.25, 0.75]))\n",
    "print(x1,x2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.11"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mean_action(grid,j):\n",
    "    x,y = get_coords(grid,j) #A\n",
    "    action_mean = torch.zeros(2) #B\n",
    "    for i in [-1,0,1]: #C\n",
    "        for k in [-1,0,1]:\n",
    "            if i == k == 0:\n",
    "                continue\n",
    "            x_,y_ = x + i, y + k\n",
    "            x_ = x_ if x_ >= 0 else grid.shape[0] - 1\n",
    "            y_ = y_ if y_ >= 0 else grid.shape[1] - 1\n",
    "            x_ = x_ if x_ <  grid.shape[0] else 0\n",
    "            y_ = y_ if y_ < grid.shape[1] else 0\n",
    "            cur_n = grid[x_,y_]\n",
    "            s = get_substate(cur_n) #D\n",
    "            action_mean += s\n",
    "    action_mean /= action_mean.sum() #E\n",
    "    return action_mean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(42)\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZgAAAGdCAYAAAAv9mXmAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAUTklEQVR4nO3df2xWhbnA8acUKZ23NIgDaSzCzBbkhwLyI0ritkgkRs1cFjcTTAgmbtmKgCRmsAWJYVBZNkMiDsVsjmSimCxEZ6KEsAhjk/BLDGabbDHXdRJAE9MqJhXb9/6xu97LrXD7lj6c962fT3L+4OQczpPznvSb8572fWtKpVIpAGCADSl6AAAGJ4EBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFEMv9gG7u7vj+PHj0dDQEDU1NRf78ABcgFKpFB9++GE0NTXFkCHnv0e56IE5fvx4NDc3X+zDAjCA2tra4sorrzzvNhc9MA0NDRER8c7h8THiP7xDdz7f/MrUokegn7YfO1r0CL24nqpXJV1PHR91x1Uz/rPnZ/n5XPTA/PttsRH/MSRGNAjM+QytuaToEeinSry2XU/VqxKvp7484qi8qQEYFAQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNAin4F5vHHH4/x48fH8OHDY86cObF///6BnguAKld2YLZt2xbLly+P1atXx+HDh+O6666L+fPnx6lTpzLmA6BKlR2YRx99NO67775YtGhRTJo0KZ544on4whe+EL/61a8y5gOgSpUVmE8++SQOHToU8+bN+5//YMiQmDdvXrz22mufuU9nZ2d0dHSctQAw+JUVmPfffz+6urpizJgxZ60fM2ZMnDhx4jP3aW1tjcbGxp7Ft1kCfD6k/xbZypUro729vWdpa2vLPiQAFaCsb7S8/PLLo7a2Nk6ePHnW+pMnT8YVV1zxmfvU1dVFXV1d/ycEoCqVdQczbNiwuP7662PXrl0967q7u2PXrl1xww03DPhwAFSvsu5gIiKWL18eCxcujJkzZ8bs2bNjw4YNcfr06Vi0aFHGfABUqbID853vfCfee++9eOihh+LEiRMxbdq0eOWVV3o9+Afg863swERELF68OBYvXjzQswAwiPgsMgBSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAU/fossoHwza9MjaE1lxR1+F52HD9S9Ai9VOJMlWh+07SiR+ilEmeCi80dDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEgxdCiB+Dc5jdNK3qEXnYcP1L0CL1U4kz0jWt8cHMHA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFKUFZjW1taYNWtWNDQ0xOjRo+POO++Mt956K2s2AKpYWYHZvXt3tLS0xL59+2Lnzp1x5syZuOWWW+L06dNZ8wFQpcr6wrFXXnnlrH//+te/jtGjR8ehQ4fipptuGtDBAKhuF/SNlu3t7RERcdlll51zm87Ozujs7Oz5d0dHx4UcEoAq0e+H/N3d3bFs2bKYO3duTJky5Zzbtba2RmNjY8/S3Nzc30MCUEX6HZiWlpZ4880347nnnjvvditXroz29vaepa2trb+HBKCK9OstssWLF8dLL70Ue/bsiSuvvPK829bV1UVdXV2/hgOgepUVmFKpFPfff39s3749Xn311ZgwYULWXABUubIC09LSElu3bo0XXnghGhoa4sSJExER0djYGPX19SkDAlCdynoGs2nTpmhvb4+vfe1rMXbs2J5l27ZtWfMBUKXKfosMAPrCZ5EBkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApLigr0y+ENuPHY0RDfpWbeY3TSt6hF52HD9S9AhVoRJfu0pUieepWq9xP+EBSCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMAClqSqVS6WIesKOjIxobG+Nr8Y0YWnPJxTx01dlx/EjRI/Qyv2la0SPQT5V4PVUi1/j5fVo6E6/GC9He3h4jRow477buYABIITAApBAY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x48UPUIv85umFT1CVajE164SuZ76xvU0cNzBAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQYerEPWCqVIiLi0zgTUbrYRz+3jg+7ix6hl09LZ4oeoSp47RhIrqfz+zT+Ncu/f5afT02pL1sNoH/+85/R3Nx8MQ8JwABra2uLK6+88rzbXPTAdHd3x/Hjx6OhoSFqamr6/f90dHREc3NztLW1xYgRIwZwwsHFeeob56lvnKe+GcznqVQqxYcffhhNTU0xZMj5n7Jc9LfIhgwZ8v9WrxwjRowYdC9gBuepb5ynvnGe+mawnqfGxsY+bechPwApBAaAFFUbmLq6uli9enXU1dUVPUpFc576xnnqG+epb5ynf7noD/kB+Hyo2jsYACqbwACQQmAASCEwAKSo2sA8/vjjMX78+Bg+fHjMmTMn9u/fX/RIFaW1tTVmzZoVDQ0NMXr06LjzzjvjrbfeKnqsivbII49ETU1NLFu2rOhRKs67774b99xzT4waNSrq6+tj6tSpcfDgwaLHqihdXV2xatWqmDBhQtTX18fVV18da9as6dNndg1WVRmYbdu2xfLly2P16tVx+PDhuO6662L+/Plx6tSpokerGLt3746WlpbYt29f7Ny5M86cORO33HJLnD59uujRKtKBAwfiySefjGuvvbboUSrOBx98EHPnzo1LLrkkXn755fjzn/8cP//5z2PkyJFFj1ZR1q9fH5s2bYqNGzfGX/7yl1i/fn389Kc/jccee6zo0QpTlb+mPGfOnJg1a1Zs3LgxIv71+WbNzc1x//33x4oVKwqerjK99957MXr06Ni9e3fcdNNNRY9TUT766KOYMWNG/OIXv4if/OQnMW3atNiwYUPRY1WMFStWxB//+Mf4wx/+UPQoFe3222+PMWPGxC9/+cuedd/61reivr4+fvOb3xQ4WXGq7g7mk08+iUOHDsW8efN61g0ZMiTmzZsXr732WoGTVbb29vaIiLjssssKnqTytLS0xG233XbWNcX/ePHFF2PmzJlx1113xejRo2P69Onx1FNPFT1Wxbnxxhtj165dcezYsYiIeOONN2Lv3r1x6623FjxZcS76h11eqPfffz+6urpizJgxZ60fM2ZM/PWvfy1oqsrW3d0dy5Yti7lz58aUKVOKHqeiPPfcc3H48OE4cOBA0aNUrLfffjs2bdoUy5cvjx/96Edx4MCBWLJkSQwbNiwWLlxY9HgVY8WKFdHR0RETJ06M2tra6OrqirVr18aCBQuKHq0wVRcYytfS0hJvvvlm7N27t+hRKkpbW1ssXbo0du7cGcOHDy96nIrV3d0dM2fOjHXr1kVExPTp0+PNN9+MJ554QmD+l+effz6eeeaZ2Lp1a0yePDmOHDkSy5Yti6amps/teaq6wFx++eVRW1sbJ0+ePGv9yZMn44orrihoqsq1ePHieOmll2LPnj0D+jUJg8GhQ4fi1KlTMWPGjJ51XV1dsWfPnti4cWN0dnZGbW1tgRNWhrFjx8akSZPOWnfNNdfEb3/724ImqkwPPvhgrFixIu6+++6IiJg6dWq888470dra+rkNTNU9gxk2bFhcf/31sWvXrp513d3dsWvXrrjhhhsKnKyylEqlWLx4cWzfvj1+//vfx4QJE4oeqeLcfPPNcfTo0Thy5EjPMnPmzFiwYEEcOXJEXP7b3Llze/2K+7Fjx+Kqq64qaKLK9PHHH/f6Aq7a2tro7q68r2C+WKruDiYiYvny5bFw4cKYOXNmzJ49OzZs2BCnT5+ORYsWFT1axWhpaYmtW7fGCy+8EA0NDXHixImI+NcXBdXX1xc8XWVoaGjo9Uzq0ksvjVGjRnlW9b888MADceONN8a6devi29/+duzfvz82b94cmzdvLnq0inLHHXfE2rVrY9y4cTF58uR4/fXX49FHH41777236NGKU6pSjz32WGncuHGlYcOGlWbPnl3at29f0SNVlIj4zOXpp58uerSK9tWvfrW0dOnSoseoOL/73e9KU6ZMKdXV1ZUmTpxY2rx5c9EjVZyOjo7S0qVLS+PGjSsNHz689KUvfan04x//uNTZ2Vn0aIWpyr+DAaDyVd0zGACqg8AAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApPgv6nGNeg9YcFoAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "size = (10,10)\n",
    "J = np.prod(size) \n",
    "hid_layer = 10\n",
    "layers = [(2,hid_layer),(hid_layer,2)]\n",
    "params = gen_params(1,2*hid_layer+hid_layer*2)\n",
    "grid = init_grid(size=size)\n",
    "grid_ = grid.clone()\n",
    "grid__ = grid.clone()\n",
    "plt.imshow(grid)\n",
    "print(grid.sum())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.12"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "epochs = 75\n",
    "lr = 0.0001\n",
    "num_iter = 3 #A \n",
    "losses = [ [] for i in range(size[0])] #B\n",
    "replay_size = 50 #C\n",
    "replay = deque(maxlen=replay_size) #D\n",
    "batch_size = 10 #E\n",
    "gamma = 0.9 #F\n",
    "losses = [[] for i in range(J)]\n",
    "\n",
    "for i in range(epochs): \n",
    "    act_means = torch.zeros((J,2)) #G\n",
    "    q_next = torch.zeros(J) #H\n",
    "    for m in range(num_iter): #I\n",
    "        for j in range(J): #J\n",
    "            action_mean = mean_action(grid_,j).detach()\n",
    "            act_means[j] = action_mean.clone()\n",
    "            qvals = qfunc(action_mean.detach(),params[0],layers=layers)\n",
    "            action = softmax_policy(qvals.detach(),temp=0.5)\n",
    "            grid__[get_coords(grid_,j)] = action\n",
    "            q_next[j] = torch.max(qvals).detach()\n",
    "        grid_.data = grid__.data\n",
    "    grid.data = grid_.data\n",
    "    actions = torch.stack([get_substate(a.item()) for a in grid.flatten()])\n",
    "    rewards = torch.stack([get_reward_2d(actions[j],act_means[j]) for j in range(J)])\n",
    "    exp = (actions,rewards,act_means,q_next) #K\n",
    "    replay.append(exp)\n",
    "    shuffle(replay)\n",
    "    if len(replay) > batch_size: #L\n",
    "        ids = np.random.randint(low=0,high=len(replay),size=batch_size) #M\n",
    "        exps = [replay[idx] for idx in ids]\n",
    "        for j in range(J):\n",
    "            jacts = torch.stack([ex[0][j] for ex in exps]).detach()\n",
    "            jrewards = torch.stack([ex[1][j] for ex in exps]).detach()\n",
    "            jmeans = torch.stack([ex[2][j] for ex in exps]).detach()\n",
    "            vs = torch.stack([ex[3][j] for ex in exps]).detach()\n",
    "            qvals = torch.stack([ qfunc(jmeans[h].detach(),params[0],layers=layers) \\\n",
    "                                 for h in range(batch_size)])\n",
    "            target = qvals.clone().detach()\n",
    "            target[:,torch.argmax(jacts,dim=1)] = jrewards + gamma * vs\n",
    "            loss = torch.sum(torch.pow(qvals - target.detach(),2))\n",
    "            losses[j].append(loss.item())\n",
    "            loss.backward()\n",
    "            with torch.no_grad():\n",
    "                params[0] = params[0] - lr * params[0].grad\n",
    "            params[0].requires_grad = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7f7290089090>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAy0AAAMtCAYAAACSEJ4GAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAADA0UlEQVR4nOzdd3wcd50//tdsVZcsy7IlW45bYsdxidOdDgkJKZAECC3cBfhSzwECxx3kfkc5ODBwdxwQuIR2CUdJIJBCAmmkOL24xHFJnLjLlrusLm2b+f2x+5kZyburmd0pn1m9no+HH4/EVhl7V7vz/rybommaBiIiIiIiIkmF/L4AIiIiIiKiYhi0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1CJef0NVVdHV1YX6+nooiuL1tyciIiIiIklomob+/n60t7cjFCqcT/E8aOnq6kJHR4fX35aIiIiIiCTV2dmJGTNmFPxzz4OW+vp6ANkLa2ho8PrbExERERGRJPr6+tDR0aHHCIV4HrSIkrCGhgYGLURERERENG7bCBvxiYiIiIhIagxaiIiIiIhIagxaiIiIiIhIagxaiIiIiIhIagxaiIiIiIhIagxaiIiIiIhIagxaiIiIiIhIagxaiIiIiIhIagxaiIiIiIhIagxaiIiIiIhIagxaiIiIiIhIagxaiIiIiIhIahG/L4CIKp+mafi3+zdD0zR8/Z0nQVEUvy+JiIiIAoRBCxG5bs/RYdz+3E4AwHtO7cDiGY3+XhAREREFCsvDiMh1m7r69P/+y4Z9Pl4JERERBRGDFiJy3eauXv2//7KhC5qm+Xg1REREFDQMWojIdZv3GZmWzu5hbNzbV+SjiYiIiEZj0EJErhPlYdObqgEAD2zo8vNyiIiIKGAYtBCRq7oHk9jXOwIA+NxFxwMA/vLqPpaI+eiG363FNf/zLFIZ1e9LISIisoRBCxG5anMuyzJrcg2uXNqG6mgYe44OY8Pe3nE+k9ygaRr+umEf1u3uwY7Dg35fDhERkSUMWojIVZtyTfgntTeiJhbBW09sBZDNtpD3UhkNai7Jtbdn2N+LISIisohBCxG5SvSzLGxvAABcsbgNQHb0MUvEvDeSzuj/va9nxMcrISIiso5BCxG5SkwOE0HLW+a36iVir+5hiZjXRlKmoKWXmRYiIgoGBi1E5JrhZAbbDw0AAE5qywYt1bGwXiL2Vy6a9FwiZTTfdzHTQkREAcGghYhc8/r+Pqga0FIXR2tDlf77V+ZKxB7gFDHPMdNCRERBxKCFiFwj+llOypWGCRfmSsT29rBEzGsjpkyLGEVNREQkOwYtROSasU34QnUsjIvEFDGWiHlq2JRp6eoZZqaLiIgCgUELuSKZVvH537+C/370Db8vhXwkmvDHZloA0xQxloh5ylwelkirODqU8vFqiIiIrGHQQq7422sHcM+6vfjhY2+is3vI78shH6QzKl7Xg5bGY/78wvmtqIllS8TWs0TMM+agBchmW4iIiGTHoIVccffaPfp/37VmT5GPpEq1/fAgEmkVtbEwjmuuOebPq2NhvHUBp4h5bSStjvp/9rUQEVEQMGghxx0ZSODJLYf0///j6k5kVJb/TDSbc/0sJ7Y1IBRS8n7MlUtYIua1sZkWThAjIqIgYNBCjrt/fRfSqoYF0+rRUBVBV+8Intt22O/LIo9t6sqWfOXrZxHMJWKvdPZ4dGUTW+KY8jBmWojIGzzApHIwaCHH3b1uLwDgfad34KqTpwMA/rCaJWITTaHJYWZV0TAuOnEqAJaIecU88hhgpoWIvPEfD7+Ok7/xCF7YfsTvS6GAYtBCjtp6sB+v7ulFJKTgHUvb8d7TOgAAD2/aj15OKZowNE0zTQ47tgnf7IrF0wAAf92wnyViHhDlYfXxCAA24hORNx7cuB/9I2l87s51ODKQ8PtyKIAYtJCj7l6bzbJcOH8KWuriWDS9AQum1SOZVvHn9Xt9vjrySlfvCHqGUoiEFBw/ta7ox7JEzFsj6WzQMmdKLQCWh7nhl8/swOd//wqGkmm/L4VICsm0il1HspNED/Ql8MW71vOQimxj0EKOUVUN9+ZKw65ZNgMAoCiKnm1hidjEIZrw57XWIR4JF/1Yc4nYX15liZjbRHnY7JZs0HKgb4R15g5KZ1R876HX9ZHvRATs7h5ERtUQj4QQi4TwxJZD+OUzO/y+LAoYBi3kmBd2HEFX7wjqqyL6tnMAuHrZdETDCjbs7dVvZqmyGU34xUvDBLFo8q8bOEXMbaI8bGZzDUIKkFY1HGaphmPePDiARG6s9C+f3oHX9/M1j2jrwUEAwPxp9fjKlQsBAN996HVs4I4usoFBCzlGlIZduaQNVVHjdL25NoaLcyfpd63p9OXayFtWmvDNLpw/BbWxMLp6R7COJWKuEpmWmngEUxuqALCvxUkb9xo3YWlVw7/esxEqM1k0wW07NAAAmDelDh86cybeftI0pDIabrhjLfpH2O9K1jBoIUcMJzN4MDf96V2nzDjmz0WJ2L3r9iI5ZrkdVR6RUSs27ths1BQxloi5SvS0VEVCaGvMBi1cMOkcEbRcsbgNtbEwVu86ij+s5mGNX/7rkS24+ifPonsw6felTGgiaJnbWgdFUfDddy/B9KZq7DoyhH+9dyMz7GSJraAlk8ngK1/5CmbPno3q6mrMnTsX3/zmN/lkIzyyeT8Gkxl0NFfjtOMmHfPn5x3fgqkNcRwdSuGx1w74cIXj6x1KYTiZGf8DqaieoST25k7urWZaAOCKJUaJGE+m3SP2tFRFw2hrqgbATIuTNuSClrctnIrPv+0EAMDKB1/ntCQfPLftMG5+fCte6ezBPes4CMZP2w5ly8Pm5gaANNZE8aMPnIxwSMF9r3Thj2vY80rjsxW0fPe738Utt9yCH//4x3jttdfw3e9+F9/73vdw8803u3V9FBB/Wms04CvKsdvPI+EQ3p3LwMh46jiczOCC/3wC1/zPs35fSuCJLEtHczUaqqKWP++CE4wSsVf29Lh0dSTKw6qiYbQ7nGnpG0nhYN/EzdqkM6o+6nvR9EZ8+OxZOLGtAb3DKXzrr6/5fHUTSyKdwb/eu1H//4c2MoPrF03TsP1gLtMyxZgmeepxzfhCLrD/6n2bsDX3MUSF2ApannvuOVx11VW44oorMGvWLLznPe/BJZdcgpdeesmt66MAONg3gmfePAQAeNey6QU/7tpcidiqNw5hv2TlKPv7siN6X9/fz8xhmfT9LG3WmvCFqmgYFy/kFDG3jeiZlhDaGrOZFqcWTL7rf57Dhf/5ZGBq1H/yxFZ85o51SGWcKVnddmgQIykVtbEw5rTUIhIO4dvXLIKiZHv+ntt22JHvQ+P76art2H5oEJNqsgcnq3cdxYEJHFD76VB/Av2JNMIhBTMn14z6s09dMBfnzJuM4VQGn7ljnf76RJSPraDl7LPPxmOPPYY33ngDALB+/Xo888wzuOyyywp+TiKRQF9f36hfVFnue6ULqgacetwkzMqNUc1ndkstzpjVDFUD/rRWrlSweZ9Cgj03ZbHbhG92eW6K2IMsEXON6GmJR8NobxKN+OXfzB0dTGLrwQEMJTOB6JHRNA0/fnwr7l/fhZd3djvyNUU/y8L2BoRC2YzzspmTcN2ZMwEA/3rvRiTSvClz287Dg/jxE1sBAP921SIsm9kETcsuOSbviQzKzOaaY0bgh0MK/vu9J2NybQyv7evDSmYkqQhbQcuXv/xlvP/978eCBQsQjUaxbNky3HjjjbjuuusKfs7KlSvR2Nio/+ro6Cj7okkud+u7WQpnWYT3nJYtEbtrdadUGQ1zL8sQ+1rKYrcJ38xcIlapU8R+88IufOH3r+B/n9mBNbuOen6yqJeHRcKOZlp2HBnU/3sgIf9Sxd7hFIZz//Zrdx115GuKfpZF00dnGf/p0gVoqYtj+6FB/GzVdke+F+WnaRq+ct9GJNMqzju+Be9Y0obLFxn9cuQ9vQl/Sv5DzdaGKvzXe5cCAH71/C4Gl1SQraDlD3/4A37729/id7/7HdauXYtf/epX+M///E/86le/Kvg5N910E3p7e/VfnZ3y9TNQ6TZ39eG1fX2IhUO4MtdIXcwVi9tQEwtj55EhvLzTmRsFJ5gDlWGmp0s2kspga+4NyuqOFjNziVgl3mCkMyq+/udNuHvdXnzjgc149y3PYdHXHsY7bn4G/3rvBvxxzR5sPdjvapbJXB7WnmvEP9ifKLtEaschI2gZDEDQYs4GrXEoaBGZlsVjgpbG6ii+cuWJAICbn9iKnYcHj/lccsaf13fh6TcPIxYJ4ZtXLYKiKHj7omkAgJd2dHMnkQ+MJvy6gh9z4fxWfPL8OQCAf/7jq/owFyIzW0HLP/3TP+nZlsWLF+Pv/u7v8PnPfx4rV64s+DnxeBwNDQ2jflHluGddtszrrQta0VQTG/fja+MRPbi5S6KGfHOgwglipduyvx8ZVUNzbQxTG+IlfY1KXjTZP5JGOheQXLSgFZNrY0irGjbs7cVvXtiNL961Hhd//yks/bdHcN0vXsD3HnodrziccTI34k+ujSEWDkHTUHa9/w7TjfjAiPxBy37T33ft7p6yA8WMqumlkWODFgB459J2nDuvBcm0iq/cxxGvbugdTuGbD2TLiz7zlnl6uXJHcw2WzGiEqgGPbJJzemUlM487LuYfL5mPpTMa0Tucwo13rkPaoV4zqhy2gpahoSGEQqM/JRwOQ1X5xJqI0hkV977SBQB41ynjl4YJYmfLXzbsk6aMxByosBGwdHoTfntD3ilyVpx3/BQA2ZPwvgDc/NrRl2tQr42F8csPn47V/3oxnvnSW/DjDy7Dx8+bjdNnTUJVNIT+RBrPbj2C/3lyG9576/OO/pyYRx6HQgqmNTrT1zIqaJHk57oY8zCQ3uEUth8ub3LR9kMDGE5lUB0NY06eE2VFUfDNqxchFgnh6TcP4wEOm3Dcfzz8Og4PJDBnSi0+ccGcUX8msi0PcorYuAYS6VFLUsu1Lc/ksHxikRBu/sApqI9H8PLOo/jRY286dg1UGWwFLe94xzvwrW99C3/5y1+wc+dO3HPPPfj+97+Pa665xq3rI4k9u+0IDvUnMKkmigvnt1r+vFOPm4Q5LbUYSmakWSQ4xJ4WR2zqMhqRS1UdCyMazgY8QSgzsqNvOPv3aajOTjRSFAUzJtXgyiXt+P+uWIi7PnU2Nn79Uvzls+fi29csRjSsIJlRcdTBxXj6cslo9uXfWDBZXjnG9sPBLQ8Dyi8R22h67odD+QP22S21WHHhPADANx7YjN7hYExZK0U6o+LfH9iM9/70eUdvgAtZt/sofvvibgDAt65efEzD92W5vpbnth1x9OepEv3zH9fjypufwWoHBlQMJtLoyv2sFeppMZs5uQbfftdiANlSynW75SkjJ//ZClpuvvlmvOc978E//MM/4MQTT8QXv/hFfPKTn8Q3v/lNt66PJHZPbgLYO5a2Ixax/lRSFEUffyzLzhbz9DD2tJROnxzWVl4ZaG08AiAYN792iExLsf01kXAIJ7U34oNnzkR97uOcyv5lVA2pTLYsqSp3U9euL5gsPdOiqtqoPo3BAAT++3NBmgjeyg1aNuwpXBpm9qkL52BOSy0O9SfwX49sKet7yiqRzuCG363DL57ZgZd2dONd//Mcbn92h2slcemMin+5ZyM0DXj3KTOwfO7kYz5mdkstTmxrQEbV8KikC45lsePwEIBsgFf+18q+LrTUxSyVkAPZe4prlk2HpgE/fnxr2ddAlcNW0FJfX48f/OAH2LVrF4aHh7Ft2zb8+7//O2Ixa09EqhwDiTQeyk34eFduaaQd7z5lOsIhBat3HdXrXf00wp6WsmVUDa/v6wdQWhO+WW0sG7QEoczIjr7cyXpDdcTSx1dHs4GFU4G0+XlelfvaTmRaDvSPjLrGIDxuItPy1gXZLHHZmZYCk8PGikfC+PerFwEAfv3CLqyvsCl5g4k0/t/tq/HQpv2IhUM4a04zkhkVX79/Mz756zXoHXI+u3T7czvx2r4+NNVE8S+XLyj4cZeLErEKHPLhJHFYtMGBDJl4f89XMlnMZy86HooCPPb6Qby+n6syKMtW0EIkPLhhH0ZSKua01GLpDPs3qK0NVbjghGzvwl2r/d/ZMnp6mPw3XDLacXhQr+mfXWRfjxV1eqalsgJIkWlprC6caTETWQCnAmlz0BLPZUfbHMi0mCeHAQFpxM8FLaJsaNuhwZLLhlRV00sjx8u0AMDZ81r0k+R/uWdDxTQc9wwlcd0vXsQzWw+jJhbGbR85HXd8/Cx8/R0LEQuH8MjmA7j8R09jzS5n9uIAwN6eYXz/0ezuuJsuW4DJdYUHgFy2OBu0PLP1cEWX5pVLBC1OlPVttdjPMtbsllp9VPWtT24r+zqoMjBooZLck9vN8q5TppfccP3e3M6Wu9fu8f1Ne1TQkqyMGwiviZu2BW31BWv6raqNZ7MAQTixt0PcKBUrDzOrjjmcacktTo1FQvryw3YHMi3bx4zwDUJZnwhaTmxr0Gvt15ZYP7/98CAGkxlURUOW6vYB4F8uPxENVRFs6urD/z2/q6TvK5ODfSN4309fwCudPWiqieJ3Hz8L58xrgaIo+PA5s3H3P5yNWZNrsLdnGO/96Qv4nye3OjLa+9/+vAlDyQxOO24Srj21+B64ea31OL61DqmMhsdfZ4lYIeJ1d1/vSNkjosfb0VLMpy+cCwC4/9V96OweKus6qDIwaCHb9vYM4/nt2VrXqy0slCzkrQumork2hoP9CTz15iGnLq8kw9zTUjbz5LByVWxPy5hG/PGI8jCnelr0HS2mHjRjwWQZmZZc0FIbC0aw2T+SQn/uGqc1VuHU4yYBKL1ETATsJ7Y1IBK29rY6pT6OL1+W3d3yX49scaVsyiu7jwzhPbc+jy0H+tFaH8cfPrkcJ3c0jfqYRdMb8cBnz8NVJ7cjo2r43kNbcP1tL+FQf+k3xY9uPoBHNh9AJKTg2+9arAfixVymj1TnAsN80hkVibRxcFdutmXbwdyOlnHGHeezaHojzju+BRlVw8+e4lJWYtBCJbh33V5oGnDm7GbMmFRT8teJRUK4Jhf0/OFlf0vERu9pkfuGS1ab9Sb88vpZAFN5WIU9FkYjvrWeliqXelrE1wWA9qZspqV7MFlycCSCFtHLJPvjJnbS1FdFUBePlB20bNhjvTTM7P2nd6C9sQqDyQy2HOgv6Xv7bcv+frzn1uewu3sIM5tr8KdPn40Tptbn/di6eAQ/eN/J+N67l6Aqmh39fPmPnsazWw/b/r6DiTS+dt9GAMDHz59T8HuOdXmuRGzVG4ekD679MLYkt5ygJaNq+mvDPJvlYYLItvxhdWdZAS5VBgYtZIumaXpp2LtLaMAfS+xs+dtrB3DEx03FQ8y0lEXTND1ocTLTUmk3FUYjvr1Mi1Mli+bFkkJjdVT/PqVmW8SNyeJcf5vsPS3i7ymGEIigZf2eHqRKKFXdYLEJf6xQSNF7ioK4qX3t7qN470+fx8H+BBZMq8cfP7UcHc3FD7IURcF7T+/An284FydMrcOh/gQ+9MsX8V+PbLFVJvzDx95EV+8IZkyqxmfferzlz5s/tR6zW2qRTKt4/PWDlj9vohgYc+BQTjP+nqNDSGZUxCMhTM89z+1aPmcylnY0IZFWcftzO0q+Fpns7RnG71/eXdJrzURn7biPKGfD3l5sPTiAeCSkNzWWY/60eiyd0Yj1e3pxz7q9+Nh5c8b/JBeYm+/Z02Lfgb4EjgwmEQ4pmD/N2olnMXWVWh6Wu5m32tNS5XB5mLFY0jivUhQFbU1V2H5oEPt6hm0PUUhlVOzO1ZuLTIPTweatq7Zh28EBfPfdSyyVAI1HBC3TcqVxc1rq0FQTRc9QCq/t68OSGU2Wv1a2Cd/auON8Wuqy0zf9PLQBss8xczA7nmfePIxP/Ho1hpIZLJvZhNs+fLrlkbYAcMLUety34lx844FNuOOlTtz8+FY8sukAZrfUojYeQX1VBLXxMOriUdTFw6iriqA2FkFdVQSDiQx++Uz2BvabVy3Se7+sUBQFly2ahv95chse2rgP71zabvlzJ4Kxr7kb95Y+ucs8OazUn1tFUfAPF87FJ3+9Bv/3/C586oK5+ij4IOoZSuL9P3send3D2H5oEDddfqLflxQoDFrIlrvXZrMsl5w0zbEXjvec1oH1e3rxp7X+BS2cHlYeUdM/d0qtrRufQmpyNyEVNz3M75HH6WPLwwBgelM1th8a1JfA2dHZPYSMquU2wWcDHqcft5sfexODyQyuP3uW7WxGPqIJv60hm2kJhRScMnMSHn/9INbsOmoraNl5ZBADiTTikRCOL6FuvyU37erQgH8LD2+8cx3ufaULk2tj6GiuQUdzDWY2V2Om/t81aGus1gdsPLRxHz57xytIZlScd3wLfvp3p6ImZv92ojoWxsp3LcHyuS34l7s3YMuBfltlcpcvnoa3LLC+2Nj4vDb8z5Pb8MTrhzCUTJd07ZVKHDiIIH5vzzC6B5NorrW/2kLvZymhCd/sbSdOxbzWOmw9OIDfvrgbn7pgbllfzy8ZVcNn73wFnd3ZoSe/eGYH3rG03ZHXtImCP6lkWSqj4v71XQCyU8OccsHx2dHH233c1zKqEZ97WmwzSsOcefGt2Eb8EZvlYTGnG/Fz5WFjtoXru1p67E8QE6Vhs1tqXcmQZVRNX1a55+iwI2/wRqalSv+9U48zgpaPnDPb8tfamHvuL7DRhG8mRvT6VR6maRoe2ZydpHVkMIkjg0m8kmd3TCSkYPqkarQ3VuPFHUegatmg4b/fd/Ix2+fteufSdpwxqxnPbz+MgZE0BhIZDCRSGExk0D+SxmAijQHTr8FEGk01MXztHSeV9P1Oam9AR3M1OruHsWrLIb05n4yf3an1VZhUE8OOw4PYuLcX5+dWFNhhTA4rrZ9FCIUUfOqCufjiXevxy2d24MNnz3LkcMxr//3oG3jqjUOoioawrGMSnt9+BP/8x1dx3w3nIFrCa8dExKCFLNt+aBBHBpOoj0dw3rwWx76uGG+bSKvIqFrZ43JLMaoRnz0ttm1ysJ8FqNxGfLsjj/VGfIf3tMSjo98gxQSxUjItetAyxQhaBpJpaJpW8jh0M3N/zJ6jzow93Z8b79xmClpOmZnta1lrsxlfNCovnl7ac39KrjzssE9Nxof6ExhKZhBSgHtXnIOunmHs7h7K/RrGnu4h7Dk6jGRGxa4jQ9h1JPsYvO+0Dnz7XYsde72e1liFa5aV3ydpRbZErA0/e2o7/rpxP4MWExG01MbDOGFSPXYcHsSGEoMWfUdLCRnIsd65tB3ff2QLunpH8Ke1e3DdmceV/TW99PCm/fjxE1sBAN999xKcM68FF39/FTbv68Mvnt6hDxyg4hi0kGXihqulPl7SiWIh5tT8cCqj3/h4yVweNsRMi22b9mVv3Ba2ORO0GI34lfVYiJHHVpdLOl4elqcRHzAmiHWVkGkRO1rmtNSiLjcVTdOyP0e1Dvws9yeMUcB7jpa+S8YsX6ZlaUcjwiEFXb0j6OoZRrvFxuFSJ4cJojzsSImLLcslgs4Zk2qwZEZT3tK4jKrhQN8IOnPBzKSaGC46sdWRoNQvly2ahp89tR2Pv3bAdj9PJROvubXxCBZPb8D967tKniBWzo6WsWKRED523hx844HN+Omq7XjfaR2O3oe4aevBAfzjH9YDAD56zmxcdXK2UuUrVyzEP961Hj/42xt4+6JpZS9lngiC8YiTFPptjmu1qioagnjvG/LpZN18ku1UKc5E0Tuc0mt0FzqWaRE9LZWTaUmmVT34sL5cMvsS7ebIY8C8q6WE8rBDRnlYdTQMcfDu1GNnbup3LNPSd2zQUhOL6EG31dHHmqZhY1dpk8OElnp/y8NE5mRWkRumcEhBe1M1zpwzGdee1oGLF04NdMACACd3NOnjpp9+0/7I5Uolfm7r4hH9OV3KBLHuwSSO5nYPzWkpP9MCAO8/owOTaqLY3T2EBzcGY8/OQCKNT/56NQYSaZw5uxk3Xb5A/7N3nTId5x3fgkRaxZf/9Kojy1ateuqNQ/j9y7ux9WCwRq0zaCHL7NbjW6Uoimm0q/cBg6ZpLA8rw2u5pZLTm6ptTQ8qphJ7WkTQD0DPSIzH8eWSohE/MvqlX2Ra9vWUUR7WUgtFUVAbc3Zctbk8TATH5RhJZdCTu5lqaxidTbG7r2XXkSH0j6QRC4cs7wkZS2Ra/CoP23kk+/jNmlz6zq0gUhQFb1+ULQt7cMM+n69GHgN6eVhE71Hcc3QYPUP2MoEiyzK9qdrWdLdiamIRfPjsbL/Z/zy5DZrm3U1+KTRNwxf/sB7bDg1iWkMVfvzBU0b1riiKgm9fsxjV0TBe3NGN36/u9Oza7nx5N770pw14dusRz76nExi0kGWitKXe4UwLYEyL8qM0K5nJ9tIILA+zR18q6VCWBajMPS1i3HF9PGK5D8D5npb85WEi09KfSI8KrsYzlEzrWQtR2mAEnM5cc/+YTEu5Nypiclh1NHzMFLdTckHL2t3WghaRZVnQVl9yI+3kXE/LYDLjy6GNCFqOmzzxSlPE2P5HXzuAZJqj7oHRmZbG6iiOywWzdkcfb8v1s8xzoJ/F7Pqzj0NNLIzX9vVh1RuHbH/+/eu78OU/vYrObmeytsXcsmobHtq0H7FwCLd86BRMyWVVzTqaa/DFS+cDAL7919f0xbduE+X+VkuVZcGghSzrs9lEbEe1j0HL2BuFEQYttjjdhA9U5p4Wu4slAePnwqnsX749LUA20BBln3YWTO48nH3jb66N6Vk2kUUy96KUw5xpGUxm9JKTUpkXS44tcTotF7Rs6uqzVKpa6lJJs/p4BLFc5suPEjHxGM5umViZFgA4deYktNbH0T+SxrPbWCIGjA5aAJRcIubU5LCxmmpi+OAZMwEAtzy5zfLnDSbS+MIfXsFn7liHO1/uxFU/eRYv7eh29NrMnnrjEP7z4S0AgH+76iQsyw36yOfDZ8/C0o4m9I+k8dX7Nrp2TWa9Nsfvy4JBC1nmVnkYANREsz84fpw0jg2UWB5mj9jR4lQTPuD8ab0MSvn5MRrxnTkFLtTTAkBvPLfTjG8uDRMcz7SMjA4eyu1r2d+X/fuZ+1mE9qZqtDVWIaNqeHXP+DdpxuSw0oMWRVEwxaexx5qmTehMSyik4O2LstkWlohlmRvxAeO5bbcZf1uu121uq/PPq/933mxEwwpe3NFtqZRz495eXHnzM7h77V6EFGBmcw26B5O47hcv4Pcv73b8+jq7h/DZO9dB1YD3n96BD+SCrELCIQXfffdiREIKHt50wJPnot2hMLJg0EKW9evbvJ2PzI1Mi/cn62ODFJaHWZdIZ/Sxlic5uCCrLtcXkcyoFVO2YYw7tv7zI4KLhMvTwwDTrhYbmZYdh7OPvTlocXqIwsCYjE25E8TyTQ4zO8ViX4umaXrJTDlBCwC0iLHHHi+YPDRgjDvumDTxMi0AcFmur+WRzQeQylTGa005jExL9ud4UbtcmRYgW856zbLsBK5i2RZN0/C/z+zAu/7nOew4PIi2xirc8fGz8PCN5+OKJW1IZTR86U8b8G/3b0Laocd+OJnBJ3+9Bj1DKSztaMK/XWVtl9CCaQ362OOv/nkTesvMKI+H5WFU8VzNtDhcBmOHyO7EcjXpibTq6RSPIHvzwADSqoammijaC9wElqImbtxUV0qJmDjZsvPzU+X0yONcI348cuxLf1su02JnweT2fJkWFxvxAZRdi77fVB6Wz6kW97V0dg+jdzhVVhO+4NeCSVEaNn1StV6iNtGcMbsZk2tj6BlK4YXtwWpKdoPYjVWrl4dlM+i7u4cs30iPpDL6z6kbQQsAfPKCuVAU4G+vHcAbB46dgNU9mMTHfrUa33hgM5IZFW9bOBV//ex5OHPOZFTHwvjxB5bhC287AQBw27M78ZHbX9Zv5EulaRr+v3s2YPO+PkyujeGW606xtXj1hrfOw9wptTjUn8C3//paWddSjKpqrt7PuWlivkpRSSq1EV98z0m1xg+vuLmj4sylYU6OQI2GQ/pNVKUsmNTfJGz0hDk9Va9oeVjuJt7Ogskdph0tguhpcSpo6U+MLQ9zKtOSfw+LPkFs99GihxeiCX/+tPqyb/hbfFowaUwOm3ilYUI4pOCSk3IlYgEZo+sm8/QwINtD0tGc/VkRr/fj2XlkEKqWzSqL57bT5k6pw9tzj9utY7Itz287gst++BQee/0gYpEQvnHVSfjZ352KSbXGtSiKgs9edDxuue4UVEfDePrNw7jmJ89iey5DVIpfPbcTd6/bi3BIwY8/eIrlXU9CPBLGd969BADw+9WdeG6rO31W/Yk0xDwTN3qU3cSghSwr5abLqurc6aw/QUv2RXqSaVwvS8Ss2exCE75QV2F9LX0lND463Yg/XLQ8zP6uFr2nZYq5PMzZIQoi0yKmGHWW29MiMi0N+TMtC9sbUBUNoWcopWeS8jGa8Mt/7vu1YHIXgxYAwOW5KWIPb9w/apKkU9IZFUd82sNj19hGfMAof7RaIrbtoOhnqXN1n48op7pvfRf2HB1COqPi+49swQd/8QIO9CUwZ0ot7v2Hc/D3y2cVvI7LFrfhj59ejvbGKmw/PIirf/IsnrI5lWxf7zB+/cIu/PtfstmRmy5bgOVzJ5f0dzp9VjP+7qzjsl/nng2u9PmK96J4JBS4paoMWsiyUqYfWVWjnyh7f6ouTp/r4hF9qpIfAwGCyJgc5lw/i1CbKxGrlLHH5WRaHNvTUmB6GGA04lvd1XJ0MKnvOzHf9Do9rlr00p04LRscuN3TEg2H9K3wxUrENjowOUwQQcshn8rDjptgO1rGOmvOZDTVRHFkMOn4RKk3DvTjkv9+Csu/8zhe3unetCqniEOCWlPQYneCmJv9LGZLZjTh3HktyKgavvvQFnzg5y/gR49vhaYB7z1tBh74zLmWRvGf1N6I+244F6fMbELfSBofvu0l/O8zOwqOV+8fSeHRzQfw9T9vwkX/9SSWr3wcX7l3I9Kqhncubcf/O3d2WX+vf377fLQ1VmHXkSH84G9vlPW18glqPwvAoIVs6NMb8Str5LH4ntWxsOM3iZVMVTV9saSTO1oE0RtRaT0tdt4oxPMxldEcaRLWRx7nqbMWCya7eoct7UIRWYjpTdWjTuscz7Tkvs6CtmzfSDm7WpJpVe8bKdTTAoy/ZFLTNP0GrtwmfMDY1eJXeZi5J2kiioZDeNuJUwEAD250bnLTX17dh6t/8iy2Hx5EMq3i3//ymvQLEQfGNOIDRjO+1QliXgUtgJFtuX99F17eeRR18Qh++P6T8b33LEVNzHpWe0p9HHd84iy859QZUDXgGw9sxk13b0AyrSKVUfHyzm7896Nv4N23PIeTv/EoPv5/q3H7czux7dAgQgqwtKMJX3jbCfjee5aUnV2qr4ri369eBAD4+dPbscHCJEM7+gIctARrQDP5RtM0femcG3O9ZehpqY5mg5ajSLE8zILuoSQGc/9Obtz0VNqult4SMpVVMeNcaSSVKXmBofE1CpeHiczDSErF0aEUmmuL16LnG3cMALUxMT3M2eWS86fWQ1Gy13d4IJl3Udt4xOK2WDhU9O93mqmvJZ+9PcPoGUohGlYwf1p5TfgAfBl5rGkadh6euOOOx7p8cRvuWrMHD23cj6+/4ySELC6AzSedUfEfj2zBT1dtBwCcNacZ6zt7sb6zBw9t3I/LFrc5ddmO0jRNf02vzVMetvPIEPpGUuMeXIqgxenFkvmcPXcyTu5owiudPVg6oxE/+sCykp/P8UgY//GeJZg/tR4rH3wNd77ciRe2H8HhgeQxmeNZk2tw7vEtOHdeC5bPaUFjjbMBwEUnTsWVS9rwwKv78KU/vYr7bjin7Nd/IciZFgYtZMlISkUqkz0hciPTok8P83G5ZE0s7HgPQSUTpzV18YhjL6ZmTpcZ+c0oD7P+shsLhxBSAFXLPifry/zZEwMm8pWHxSNhtNTFcHggia6eYQtBy7HjjgGgLneNYxvoSzWQ+3ebVBvDtIYq7OsdwZ6jQyUFLfv7jNKwYqehYhHc1oMD6BlK6oszBXHifMLUelvTgQppqfe+p+XwQPbQIaRAb7SeyM6eNxn1VREc7E/gg794Af906QI942ZH92ASn7ljLZ7dmp1E9skL5uCfLpmPHz32Jn70+FZ87+EtuHjhVFdeM8uVSKt6T485aJlUG8P0pmrs7RnGpr19Rfs1VFUzelqmuB8MK4qC//3w6Xh5ZzfeMr+17KEYiqLg4+fPwbypdfjs79Zh55FsCeWkmijOnteC8+a14Jx5Lehodr+k8uvvPAnPbD2Mzfv68MimA7hiiTPBbpCDFvl+akhK4oYrHFL0AMNJeiO+HyOPU6I8LMKgxYY+F/f2AJWXaSmlJ0xRFKNkMVl+eVix6WGAuRl//L6WQpkW5/e0GI3BYpdIZ4l9LeP1swjNtTHMyd1wrdvdc8yf6034DvVyiZ6WnqGUZ7tCRGlYe1O1I4FX0MUjYfzL5SciFg7hhe3dePctz+Fjv3pZL4G1YsOeXrzj5mfw7NYjqImF8ZMPnoKbLjsRkXAIHz9/DibXxrDj8CB+/3Kni3+T0pkPiGrHlFZZXTK5v28Ew6kMomHFkxt7IPvzeulJ0xwd2/2W+a24/zPn4htXnYQHPnMu1vzr2/CTD56C958x07O/V0tdHG+Z3wrA3tLf8QR13DHAoIUsEjdc9VURV6aBGJkW729Qh8yZFodHzFYyNwczAEYj/mCFPBal9oQ5GUgb5WH5X/qNBZPjv0FuP3Ts5DDAOKF1KmjpN/27zZiUDar2lDhBbH/u71Wsn0UQ+1ry9bVsyC2VXDTDmaClqTqKcK4c6YhHCyZ3Fgg6J7IPnDETT/zThXjfaR0IKcDfXjuIy3/0ND535zr936uQu1Z34t23Poe9PcOY3VKLe1ecM+pkvL4qis+8dR4A4Ad/e1PKwxhxTdXRsP58FBbPsNaML0rDjptcK2U2yY5ZLbX4++WzsGh6Y1nlguUQ2ZCeYedeF5hpoYrn5rhjwN+eFhEoVUfDesaHQcv43D6tqbjysBJGHgPQT8GdGA4hvkahk3UxQaxrnAliqqrpJ/Vzxva0OPi4ZVRNf02oq4pgRu6Es7Pb3UwLYDTjr941euKTpmn6abMTTfgAEAopejmeV30t4vGb6JPDxpreVI3vvmcJHv3CBbhiSRs0DbjvlS5c9P1VuOnuDfrIbCGZVvGv927AP/3xVSTTKi4+sRX3rjgn78LRD555HGY21+DwQAL/+8wOr/5Klo3d0WImxtqPl2nZelA04TMYdkJTrlemx+JiTytK6a+UBYMWskQ/JXahCR8wpiT5Pz0sN/KY5WHj0je8uxTIVlJ52Egqg0Q6m+Ww+0bhVKZF0zT9GqoLlHhazbTs7xvBSEpFNKxg+pgFavUOBi2jylXiYQcyLcV3tJiJoGV9Z++okq19vSPoHkwiElKwwIEmfKHF42Z8Uas/0Xe0FDJ3Sh1+8sFT8MBnzsVb5k9BRtVwx0u7cf5/PIFv/WUzugeTONA3gvf/7Hn85oXdUBTgC287AT/7u9MKnmDHIiF88dL5AICfPrVdut0tYniGeXKYIAL07YcH9aE8+Xg5OWwiaNIzLU4GLfYnWcqCQQtZop8Su5Zp8S/DIW4GWR5mT5+L0+SAysq0iBKnkALU2RjDCRgBfblBiwhYgCI9LRZ3tYh+lpnNNYiMKQFxsjxMPPaxSAjxiDloKS3TYjTij994PndKHRqqIhhOZfD6vn7990V5zPFT6x1dzCY2hx/2qDyMiyWtWTS9Ebd95Azc9anlOGNWM5JpFT9/egfO++7juPyHT2Pt7h40VEXwv9efjs9edPy4ZURXLm7DoukNGEikcfPjWz36W1gzWCTTMrkujvbcoYZYKpyP0YTPoMUJYghIrxuZFpf6Ud3EoIUsEZmWepee5PqelpT3N6ijp4flgidmWsbldiArRucOOTQ610+9ek9Y1HZttNGIX96/g7m8rKpAw6q4KekaJ9OyXe+HOPbGRNzwpDIaEunyrlksuhPZG9GIv/foMNQSNpfvt1EeFgopOEXf12KUiOlLJR3eTeRlpiU77jiXaWlheZgVp89qxu8/eRZu/8jpOKm9AYPJDI4MJrFgWj3+fMO5eMuCVktfJxRS8OW3nwgA+O2Lu7D7SGlZQzcUKw8DrC2Z1DMtHow7ngjEKGUne1qCvKeFQQtZ4n6mxb8MhygPq4qGHTvVngi86mkZ9GE4g9PKyUpVOVQeJprwIyHlmOyIIDItB/pGigYFO3JN+HPy1K3XmkrPyt3VIspQ6nKHJW2NVQiHFCQzKg7aXMSYNn2OlUZ8wNSMb5ogpi+VdKgJX2jxcMHkkcHs3glFgWeTkCqBoii4cH4r7r/hXNz6oVPwT5fOx93/cDZm2RxmcO7xLTjv+BakMhr+85EtLl2tfYOmSX35LBpngljfSEr/Gcv32kD26eVhDmZaGLRQxXP7BtXX5ZJ6eVgE1bllfiwPG5/R08LysPGUE/Q71Wc13rhjAJhaH0dIyWZJip34F9rRAgCRcEgP/sstERO7XkSGNxIO6QGH3b6WwwNJZFQN4ZCiZzXGc+qsbNCyNjdBzNyEv8ihJnxBXJMXu1rEJKz2Ro47LkUopODti9qw4i3zbG1dN/vS2xcAAP68vsvypnm3jZdpWTxOpkVMFJzaEHftgHOicbM8zOmFmF5g0EKW9Jc4rtUqc7Oxptkv+yjHiKk8zM/emqBxO5CtpEb8UscdA3Csz6rYYkkhEg5haoMoESvc11JoR4sgbnrE60apRHmY+eS31L4WMVxgan38mHGuhSyd0YRwSMHenmHs6x3Ggb4EDg8kEQ4pWNgW3PIw0YTPccf+WTS9EVed3A4A+O5Dr/t8NVnFGvEBI1Dffngw7+vytoNswneayLT0J9KO7HDSNI0jj6nylTqu1SoRLGiaUcbiFdFHUx0L66fQLA8bn+s9LXrQEvzHopyfHxHQlzvyWPxcjXeyrk8QK7DMLJlW9eWOY8cdC/qCyTJL+4zFksZzTF8w2W0v02Knn0WojUdwYlt2QtjaXT1GE35rnaNN+ADQUp8NWg55UB4mMi0cd+yvL14yH9GwgqffPIyn3zzk9+XoP69jF0sKU+rjmNZQBU0DNudZusnJYc4zHwr2OTBBbCiZQTpX+hvEbBiDFrLEaMR3KdNiugEY8riHQZxgV7OnxRa3x2CLG9+KKA8rY8+RU4G0UR5W/GVf9LUUyrR0Hh1CRtVQGwtjSn3+MiunSvsG8gwAmZELWuxnWnLjji1MDjMTfS2rd3XrQctJ7c6WhgHA5Frvpoft5OQwKXQ01+BDZx0HAPjOg6+XNFzCSfohQZGSX70Zf8+xJWLc0eK8cEjRS7CdGHss3osiIUUvyw8SBi1kSZ/LI/LCIQXx3EQjr/tahkaVh3HksVW9nmVa0p6XDDqtr4y5+EZ5WHkZSCs9LYBpgliBTItowp/VUgtFyV9m5dTY4/48jcEdzdmgo9NmT4sx7th6pgWAPkFs7a6jpqWSzpaGAdADwO7BhOs3r3rQwvIw393wlnmoi0ewqasP97/a5eu1jNeIDwCLphdeMsnJYe4QfS1ONOObS8MKvX7LjEELWeJ2/wJgmiDmYZZD0zT9+7E8zB63J5CIG9+0qo3aMRJE5WwgFs/JkTLHB4vysPGCFpGJKLRgcrx+FsC0YLLMnhYxPczZTIu9oEUsmdzU1YdXOnsAOD85DACac5kWVQOODrmXbdE0DbvEuGOWh/lucl0cnzx/DgDgPx/ZgqSPr3XF9rQIhZrxUxkVu3K9UiwPc1ZTrmG+14Gxx6KhP4j9LACDFrLI7e3ngNHX4mWmJZFWIQ7xs9PDmGmxopwN71aZ66qD3oxvlIeV0NPi0J6WhIVGfABobxKZlvzlYWJHS6F+FsD58jBzuYrItHT1DCNjIyOxPxeE2c20TG+qxtSGONKqhu7BJEIKsLDN+aAlGg5hUu7mxM0Sse7BJPo57lgq/++82ZhSH0dn9zB+++Iu365jvOlhgBG0bDs0MKqUe3f3ENKqhppYGNMa7P2MUXGNDo491neGTYSgZdasWVAU5ZhfK1ascOv6SBL9Lm8/B+BLwGAOkKqjYV+yPUEkpkIpinGq7rRwSDGNzg3249FXTqbFsT0tuaBl3Eb88TItuXHHRerWnRqiIG6izM+x1voqRMMK0qqml3xZUWqmRVEUPdsCAPNa6/TXKqdN9mCCmCgNa2+sdnyYAJWmJhbBjRcfDwC4+fGt+vut18abHgYArQ1VaK2PQ9WA10zN+GJy2JwptbYX6FJxbpWHBZGtoOXll1/Gvn379F+PPvooAODaa6915eJIDl6cqgPm8jDvTtXFSVEsEhp1k8xMS3Eic1AXj7j6BlUpu1ocGXns0PSwccvDcpmWg/2JvCM2jfKwwiUgjk8PM2VawiEF7blhAXssThBTVQ0H9J4We434AHDqcc36fy9yoQlf0BdMuhm0iNKwFmZZZPLe0zowp6UW3YNJ/Pyp7b5cg14eNs7umXzN+NtyvW7zWBrmOH3BpCON+KX3V8rAVtAyZcoUTJs2Tf/1wAMPYO7cubjgggvcuj6SgPlUva7ERVpWiJszL8vDRlJGEz7g3KSmSuf2uGNB3Px6PVHOaf1lZFoc29OSe07HxykPa6mNIxpWoGnQb/SFwUQaB/qyN9Szi0yeEiOKyw02+/U9LaP/3fSxxxb7Wo4MJpHKaFAUoLXAxLNizJkWp5dKmhm7WtwrDxOZluM4OUwq0XAI//z2+QCAnz+9w5N9PWNZKQ8DTEHLXlOmheOOXSMCjF4Het2MTIt793JuKrmnJZlM4je/+Q0++tGPFp1AkEgk0NfXN+oXBYtXp+oicPAyaNEnh+VuDDk9zBpj3LG7QYvocwp+pqWcPS3Zl2mn9rSMl2kJhRS972PfmLHHIssyuTZWdJtyrRhX7UIjPmBeMGkt0yJ2tEypiyMatv+2t7CtQZ9u6EYTvuDFgkmxWJJN+PK59KRpmDulFsOpDNbuOur597cyPQww+lrME8Q4Ocw9ohHfkUzLRCoPM7v33nvR09ODD3/4w0U/buXKlWhsbNR/dXR0lPotySdenar7sY1eBC2ib0CcaiczKtIObJ+tVG6PwBbqKmDBpKZpZY08dmxPS9paTwtg9LWMHXtsZXIYYH7cnFouOfp5JhrIO7utZVpEf47dfhYhFgnh369ehE+eP0ff2+IGvTzMxQWTYrEkd7TIR1GM0sf+MgN+u1RVw2Du/XC8TIsIWt482I/hZAaappl2tDBocZobjfhBXCwJlBG0/PKXv8Rll12G9vb2oh930003obe3V//V2dlZ6rckn/R7dKpe7UOmZTg5ujzM3GA7EvAxu27yYgQ2YJzYB3l62EhKRTIXAPvb02Jtehhg7GoplGkZL2hxc7kkUEKmpcQdLWbXntaBmy4/0dVss8i0HBl0pzxM0zTuaJGceI3wuhnf3H82XqZlakMcLXW5Zvz9fTg0kED/SBohBTiOGTzH6Y34zLSgpGPSXbt24W9/+xvuvvvucT82Ho8jHrdfQ0zyKGdcqx1GaZZ3N6jiRrAmmv27xSMhKAqgadk+ivFevCcqL0ZgA5XRiC9+fsIlbiA2puqVu1zSWnkYAP20d1+hTMs4G69F43w5jfgZ08nv2J9Du7ta9uuTw+w34XvJ7fKw7sEk+key445nctyxlESA3udxpkVks0PK+AcbiqJg0fQGPLnlEDbu7UUi99rS0VzDiXQu0Pe0ONrTEsygpaRMy2233YbW1lZcccUVTl8PSUjcoNa7fIPqR6ZFfC/xvRVFMe3FYKalkHJ6NOxwqszIT+ZSulI2EOvPxzIzLQkbmZa2XNDSNSbTYmVHC2A8buX0tIw6+R1zYNIxyRjLnG/C2VgiaCkn0+KFltyQALfKw0Q/S1tDFW8uJSWy115nWsxN+FZepxabJoixCd9dTk4Pm3BBi6qquO2223D99dcjEuEp9ETg1Q2qPj3Mw8ldIqtTbXoDd6ocp5J51eekZ1oCPD2s3FK6KoeCFr2nxUqmRS8PMzIZmqZhR+7mpNi4Y8AYmTpQRi+SKEuNhUOIj+nDmVIfRzwSgqoZAUkxosxN9qV3k2vFyOMkNM364kyrdrE0THpiJ5HXPS1Wm/AFY4KYOWjh88oNYuhJ73AKqo2Fuvn0ljHJUga2g5a//e1v2L17Nz760Y+6cT0kIe8a8f1bLmku26nSRy8H90bZbV6d1tRWRKalvFI68XxMq5qlrEIhenmYjUb8fT1GQNA9mERfrrRovLp1JzJkhfpZgGxGdHou29JpYVeLEz0tXpiSy7QkMyr6XXjOiyZ8jjuWl3i++xW0jNeELxjN+APY3JWdCstMizvE+6ymlf+8mHCZlksuuQSapuGEE05w43pIQt414mdfLL0MFkQ2xdyAX+PQBvJK5tXIY31JYYCnh5WbqTRnAct5Tlrd0wIA7bkFk0cGk/rniX4WK5vUxQCF4VQGmRJPBgcSuVHrBXrprPa1aJpW9vQwr1RFw3rA50aJGMcdy0+UYff5WB5mRVtjFSbXxpBRNby8sxsAMI/jjl0Rj4T1+5Ke4dL7WrxaFO6mkqeH0cThWSO+D8slx04PA4wAptxynErm1cjjSmjEL/dkKxpWEM5NrBop42fDmB42fqalsTqqB0uitErvZ7FQAmIONEp97IzFkvmfY6KvpXOcCWK9wyk9yzRV8vIwwDT22IUFk5wcJj/fMi1J8fNmrddJURSclMu2iHMJZlrc0+TA2GNxL6coRhli0DBooXFNhPIw82l2lQ/BU9B4NfK4shrxS/u3Mg+HKC/TYn16mKIoaMtlW8QEMavjjoHsyWA0nA20Sn3sCu1oEaxmWkTQ1VwbC0TzuVsTxDRN0x9D7miRV71PI49F/5noR7Ni8fQG/b+ba2OYlOvJIuc1OjD22Pxe5ObodjcxaKFxGaVALjfi+zo9zPi7+RE8BY1nI49jYnRucB8LJ0rpnFgwaSyXtPay3944eoLYjkPWgxag/H6k/iI9LQDQ0Wytp2V/QJrwhcm5TMsRh4OWo0Mp/d+UuzTk5XdPi50x/6KvBWATvtuMTEvpGVijCT+YWRaAQQtZ4F2mJfuD5GUviSiZGVUe5tC0pkrm1US5mgpYLulEKV11LPtSXU4gnbCRaQGM/o9SMi2AeYJYiZkWPWjJ/7pjN9Miez+LIDIthxwuDxOlYW2NHHcsswafelrsNuIDxgQxgKVhbmsyTRArVdCb8AEGLWSBV6VANTHvp3aJ71WdJ2hheVh+I6kMkh4181VEeZgDPz/OlIdZ72kBRu9qUVUNO46IHS3Wbk7EiXGpQxT6xzn5FT0tB/pHkEgX/h77c034sk8OE9wqD9vJ0rBAEAdBIym1rGmBdtltxAeA6U3V+s00gxZ3GQsmyykPyz7GDFqoounTwyp5uWT02EZ8Tg/Lz9zMV2ej/rkUldCI70QpnRPZvxEbyyWB0btaunqHkUyriIaNUcPjMR670t5kRaal0PSw5toYqqNhaBrQ1VN4V0vgMi0uLZjUJ4e1sDRMZuYg3csSMaM8zHoWTlEUvHVBK0IKcNacyW5dGgForC6/p4WZFqp4qYyq39i7XgrkQy/JcJHyMAYt+Ymb8Pp4xPVmPnOmxY1le15wopQuLp6TyTL2tKRtloc1Gbtadpj2e4QtPuZG0FLaz5E+8rjAya+iKHpfy54iE8SMHS3Wgi2/teSamY8MOlseJhZLckeL3CLhkP5+5GUzvsiI2ulpAYBvX7MYT/3zW7B4RuP4H0wlE5mWcqaHMWihimc+6bH7YmZXTTT79dOqppcfuW1Yb8TPk2lheVheXpULAsaNr6oZ06+Cxok3inIzLamMqu9LsbJcEgCm56aHdfUO2+5nAcw7dsqbHlaoER8w+lo6uwv3tQQ208LysAnLj2b8UsrDgOwhiPg5JPeIRvzeMva09HrUn+wmBi1UlGgiro2FEQm7+3QxBw5eBQxD+p4W44WaQUtxXg1mAIzdPUBwS8Sc+PcqN/tnDnasLJcEgLZcZqJ/JI0Ne3oBAHNsBS3llfaNNz0MMPpaimZaxPSwoAQtdSwPm+j8WDBZyvQw8o6TmZagLpYEGLTQOLw8VY9FQojkSk+GUt7coIqbwFE9LSwPK0qM8PUixRwKKaiNBXeCmKZpjow8LnfhqchSKQoQtzjyuDYe0SeePbftCAB7mZZy+5GM5ZKF/930TEuBCWL9Iyn9+wdl5LFYLjmYzDh2cHJ0MKnfsBzXzEyL7IKUaSFvONHT0sfyMKp0XjXhC14344vpYXl7WphpyavP41nvQW7GH0pm9LKscn6Gqsp8TopgJx4JQVGs9yG15/pa9ubGHtsrDytv8tt4yyUBYMY4mRaRZWmoigTmZqwuHkEsF1g6VSImxh1Pa6galdEmOemZljJuUO0aTDJokRl7WrIYtFBRXt+getmMr6qafgKdt6eFmZa8vK6LDfLYY5GpjIYVy1O78ik3+ydGAtvdzzG2D2S2jQVy5QabA1bKw5qL97SIJvy2gDThA9kBA1McHnssghaWhgWDH5mWUhvxyRvGnpZkyUNpGLRQxRM3XYUWvDlN9JZ4kWkZMe124PQw67wsGQRMm9U93N/jFPO4YzsZjrH05ZJllodZbcIXxAQxIHszI26mraj1MNNyeCCRt3RuX8D6WQRRInbYoQWTOw/n+lnYhB8I4kDIn/IwZuJk1JQrD0tltJLvj/rY00KVzrjp8ub0xVjs6P6LtfkH33wzx0b84pzYO2JHrT6FKniPh1MBXrnTw4Zt7mgR2k03+7Nbam0FXvV60GL/mjOqZgQtRV57Gquj+vfZk6evZX/AJocJTi+YNDItDFqCoEHPtHhTHpbKqPrETmZa5FQVDello6X2tTDTQhXP61N1L8vDxPeoioZG7RupYXlYUU7sHbEjyOVhYntxuT8/TvW02C8PMzItdvpZACPT0l/C42bOqhUrD1MUY9llZ56+lqBmWiaLTItDE8T0yWGTWR4WBF6Xh5lfW9nTIidFUfSxxz1D9jOw6YyKwdz7B4MWqlhejrcFvG3ENxZLjn6RLvcGsdJ5/ZwQj08QG/H1AK/MTGW5fVaiPCxuN2hpGp1psaO2jD0top8lFg4hPk5Jm+hryZ9pyf5eUCaHCSLT4tSCSS6WDBZRjt2f8CbTIoKjWCSEqMurDah0el9LCc34faYA2KvKGTfw2UlF6dPDPG7EH/IgyyECo+oxN3KcHlacEyN87agto8zIb07VEIvyxeESF2zqmRaL446FdlOmZY6NJnygvAyZldIwQZ8g1l05mRYRtBxyoDysZyipTxw6jpmWQPA805LkjpYgaCpj7HGvhzv33BTcKydPGCfF3p6qD3vS05L9HmNHgOrXwPKwvPqHnckeWKVvVg9iI75DI8PL39NSWnnYtMbSMy3lLJc0drSM/xzrmFQk0xLA6WEA0FLv3IJJURo2tSF+TFaZ5GQsl/S2PIxN+HJrLGPscSX0swAAX8GoKNF07dX0ME/Lw5KiPCx/piWtakhlVKbLx/Brelggy8McGhlebiP+SK7J1m4jflU0jItPbMXu7iGcMLXe1ueaMy2aptlq4hcNyFaClhkFelqGkxn9zT1wmZZaMT3MgaDlcK4Jn6VhgaFnWjza0zKQy2LXMqiVmt7TMmy/bLQSJocBDFpoHF43Xdd4WJolMiljy8OqYqFRH8OgxaBpmjE9zKMXvyA34juVqSy3zypRYqYFAH7+96cBgO2RzSLYVLXsz5GdU34RoBZrwhcK9bSILEtNLBy4Gm6RaXGip0WfHMagJTDE897rTAvLw+RWTk9LpWRaeDdGRXnfdO1dpmWoQKYlFg4hnJsmxr6W0RJpFclM9tTeqxvBcvd9+KnXodOt8hvxRU+L/aBFUZSSdszUxMIQn2Y3S2ZlsaQgpod1DyZHPUf2iSb8xqqyduT4QfS09AylkMqU1sck6JkWjjsODGNPi1eZFlEexqBFZk01uZ4WBi1E+fV73HRd7eFySRGQjO1pURSFzfgFiCA2pHh3Khfs8rDsNZf7RlF2eViqtPKwciiKgrpYaUMUrCyWFBqqovq/rznbEtQdLUC2DEQcnBwpc8Ekxx0HjwhaEmljf4qbmGkJhsYyysOcOkDzG4MWKiijavqOBa9O1Y0dKd4tl6yOHvt308tx2Iw/irmfxavT67pKWC5Z7shjn/a0lKvULJneiG/x362jOTdBzNTXok8OawhWEz4AhEIKJjvU18Jxx8Fjft57kW1hI34wNJXRiN/HTAtVugFTPW1lNuJn/35jy8PMv+fFdQRJr8flgoDRHBrE8jCnhhaIPqvhVAaaptn+/JF09nlsd09LucRNkN3Rrcb0MGv/bjOaslmETtPY4yBnWgBgcq5ErJygpXcohaO5G5xZLcy0BEU4pKA2VtrPTin0RnxmWqQmRh73ljCgQbwXMWihiiWe5FXREGI29zuUystgwVgueeyNXLnlOJXKaML37s1NP60P4shj8e9V7sjj3PNR1aD3FNnhR3kYUPoQhYHcUj0rPS2AOdNilIcFdUeL0FInMi2ll4eJJvzWeo47Dhp9waQHQQvLw4KhnEwLe1qo4vlxqq6Xh3nYiJ+vZKbKw+sIEq/39gDmG99gPRaqqumlHeUGeebn6EiylKCl9Eb8cpQacNqZHgYAM3K7Wsxjj/f3ZQOYoGZapjiQadEnh7EJP3CMBZNelocxaJGZEz0tDFqoYnndhA8Y/SVDHpyqF9rTAhijl4eYaRnF62lyAFBjWi5ZSmmUXwaTaai5yy333ysaDiEiJtqV8JwUmZaxQyfcVuqCSTvLJYH8mZb9Qc+0OLBgcudhNuEHlTH22P2gxc7gC/KPyLSMpFTbVSC9Du0M8xuDFirIqSZiO/zItOQtDxMbyJlpGUXf8O7hC594I9W0YPUYiTeJWCTkSAN8OSWLibTIKvpTHjZgs8TF7k2UnmnJ9bQk06peVtXWGLxGfAB6I345u1qYaQkuUR7mxa4WkQll0CK3unhEnypot6+FmRaqeOJU3asmfMDU0+JBhkNfLpmn1rua08Py8iPTUh0NI/c6HahmfKfGHQtVZexq8b08zOXpYTNyu1r6RtLoHU7hQG6xZCwSwqSaYL5JtzhZHsbJYYEjKhzYiE+Coihoqi6tr8Xp9yO/MGihgvr8KA/zdHqYGHlcONMSpJN9Lzg1DcsORVH0CWJB2tXidKaynEDaaMT3J2gZsLunZcTeAIOaWETPTOw9Ooz9fcbksKAtlhREedihssrDxLhjlocFjT89LRx5LLtGvRnfegZWVTVf3rvdwKCFCjJO1b0sD8t+r2RaRUZ1t39hKFV45DEzLfkZ07C8PZGrDWAzfp/Dy7z08rASAmmRaYl7XB4mbrzsTw+zX64isi2dR4dMO1qC2c8ClD89bNS4Y2ZaAscIWjg9jAxGM771YLY/kYbmUH+l3xi0UEF+RObmAMLtZnx9uWSxnhYGLaP4dVojTgCDlWlxZtyxUFZ5WLrwpDw3iV0Tdh43VdWMoMVGcDyjOZtN2HN0GPt7gz05DDDKw7oHE1BLOMDZ1Z3Nskypj7PsJ4Aa9JHH3jXi83kiP1Ee1mujPEwcoMUd6q/0E4MWKqjf4ZsuK+KREEQ1h9vN+CPFGvHF9LAA7gZxk19bdUvd9+En5zMtxoJJu/TyMJ96WuwELebxyCVlWrpNmZaANuEDQHOu3E3VgKM2SkGEHbnSsNnMsgSSV5kWTdOYaQmQpprs64KdsceV0oQPMGihIvp8GJGnKIoxbtjloEU0+xfraRkuYSdGJfOjzwkI5oJJ13payigPC8JySRHgRMMK4jaW2nZMMmdaRHlY3PLnyyYaNoYIlFIitutIdpIa+1mCyaugZSSl6qPZmWmRX2MJjfh+HTa6gUELFSRuurycHgYY07xcD1qKlYeVMV62kvkxPQwo7cTeb71OZ1rKKFlM+NSIL8q77Dxu5h0tdproRaZlz9HKyLQA5U0QE034HHccTPVxMfLY3fIw889mTcBLhyYCsavFTk8LMy00IfjVdK3vakm5d4OaUTUk02ru+xUeeczyMIOmmSeQePucECf2Q4FqxHd45HGJwyEyqoZkxt/pYXYyZCJosXtY0mHqadlXAT0tADBZb8YvIWjhuONA8yrTok8Oi4URCgVz0t5EUkpPi9MHaH6yHbTs3bsXH/rQhzB58mRUV1dj8eLFWL16tRvXRj7zq+m6xoNxw+Ybv2LLJTk9zDCcyiCVydYReJ9pCWIjvrNZKT1osVmyKBZLZr+G/MslS93OPb2pWv/8A33Zm/ygBy1GpsVeeVg6o+KNAwMAgDlTGLQEkbGnxZtMC0vDgmGi97TYepYePXoU55xzDt7ylrfgwQcfxJQpU/Dmm29i0qRJbl0f+ciPRnzAmx0pIoOiKMhbN2+MPGZPiyAyB+GQkjfQc5PY0xLMRnx/97SMmJ7D/i2XtH7NAzYXSwpV0TBa6+M4mNtrEgkpmFwX3J4WoPTysFf39mIgkUZjdRTzp9a7cWnkMpFp6XM501LqIQH5Q+xp6Z2g5WG2nqXf/e530dHRgdtuu03/vdmzZzt+UeQ/VdX0Ex6vS4H08jA3My2mxZL56uaNRvzg3CS7zdxY7vXCvmA24jsb9JfaZyU+PhYOeV7+USf2LmVUJNMqYhYa6wcSuV66Em6iZkyq1oOWqQ1VCAe83GVKbsHkYZsLJp/behgAsHzOZJb8BJQoj0ymVSTSGcRdOnAYZKYlUJpKacSvkMWSgM3ysD//+c847bTTcO2116K1tRXLli3Dz3/+86Kfk0gk0NfXN+oXyW8wmdYninieaYm634g/VGTcMcDysHycHuFrR6mb1f3k+MjjEhvx/VosCYzesG01S9ZfYqYFMPpaAGBawEvDAGBybuzxkUF75WHPbTsCADhn3mTHr4m8Yc58uNnXYpSHsQk/CER5mL2eFn/6k91g611s+/btuOWWW3D88cfj4Ycfxqc//Wl89rOfxa9+9auCn7Ny5Uo0Njbqvzo6Osq+aHKfOCWOhUO2xo46wehpce+FWgQj+SaHAebxsiwPE5zu0bCjLveGGsjyMIfeKEptxB/xaXIYAETCIb2Pxmo/ktGIX1qmRaiEoKWU8rCRVAardx0FACyf2+LKdZH7wiFFD1zcDFpE6SbLw4JBZFr6E2mkMtbuTyqpPMzW3aiqqjjllFPw7W9/G8uWLcMnPvEJfPzjH8ett95a8HNuuukm9Pb26r86OzvLvmhyn7ke3+tSIK/Lw/Ixgpbg3CS7TZ8m53G5IBC8kccZVUN/wtmdNqXuaRlJ+7OjRaiz+dgZNfb2/91mTDIyLW0NFRC0lFAetnb3USTTKlrr45jLJvxA0/tabPQv2MXysGAxv59YfV5M2KClra0NCxcuHPV7J554Inbv3l3wc+LxOBoaGkb9Ivn5tY8DMDXiu1iaZexoyf9CXWMqD9M0zbXrCBI/My21JSwp9JN5WpZjPS2x7Mu1/UxLLmjxuAlfsPvYDZSRaemYVFnlYS36yOOk5deh57aK0rAWzw+cyFlejD3m9LBgCYcUPXtvdVdL/0QNWs455xxs2bJl1O+98cYbOO644xy9KPKfXqLhw5Pci0yLKD0rtEyrKncNqgZ9x8VE5+dW3VI2q/tJBHjV0bCl5nMrSm3E92uxpFB6pqW88rC2gC+WBIzysGRG1TN343luW64Jfy77WYJONOO7OfZ4kNPDAkcfe2yxr0XPtNRMsKDl85//PF544QV8+9vfxtatW/G73/0OP/vZz7BixQq3ro98Yp4U5TWx7NHNnhZx41ewEd90g+dm8BQk+jQsPxrxY8FqxO91eNwxUE5Pi7/lYXbHHovXnlJuotqbqiGSC5WQaamKhvV/ByslYgOJNNbv6QUAnM2gJfAaPMi0iImMtQWqDkg+TfrY4/EHdGiaZrwf+VAl4TRb72Knn3467rnnHtxxxx1YtGgRvvnNb+IHP/gBrrvuOreuj3zia3mYvo3e/fKwqgJBSzQcQjScvfvhBLEspxvL7QhqpsXJn5/ye1r8zrRYOxUUmZZSysNikRDOnN2M5toYTphaZ/vzZWQuERvPyzu6kVE1zGyuGdXfQ8EkMi19LmZaxEEQp4cFR6ONscdDyQzSuVGwlVAeZvtd4corr8SVV17pxrWQRIxTdT8yLV6Uh+UyLUVu5KqiYaQyaWZacvyc9S7eUIdTGWRUTfr9G8bQAuf+rar08jB75Yri493a8zAeu+OqS10uKfz2Y2chmVYLTgYMmpa6OHYeGbI0QezZ3H4WjjquDF70tLA8LHjslIeJLEvEh6XQbvCnXoCkJ0UjvgfTw4r9EHuR8QkS/Ubcx0Z8wN2yQae4kZUqdXeQ3+VhdrNkeqalhOlhQLZRtVICFsDoazliIWgR+1k46rgyGD0t7jfil3pIQN7TF0xaaMQXh42N1dGKGMzBoIXy6vexf0HvaXGxLMvY01L4hbqmxGV+lcqNPg2r4pEQIrnsitXeCD+5kZUqtRHfzz0tgP0dO+VmWirN5Fx52KFxysOODiaxeV92efPyOcy0VAIj08KRx2TQe1qGxi8ZFUsoK6E0DGDQQgX424jv/o6UoXH2tAClNz5XKj9HHiuKkdoOwq4WNyatmZ+PdsZw+51pETdDVqZfqaqGgSTLVcysLph8YXs2yzJ/aj2m5Pa7ULCJ9183e1pYHhY8jTYyLeKw0Y9JsG5g0EJ5iRfJ+ootD8uNPC5WHubBdQSJsXDUnxe/IDXj6z1hTjbi556PmgYk0tb7WvRGfJ96Wuw8boPJNEQ8VkojfiWyumDyWY46rjjelIflGvE5PSwwSulpYaaFKpqf28+9bMQvVvvO8jCDpmmu3IjbEaQFk31ujDw27Xux85z0e0+LncdNZNGiYQVxh/bbBN2UXHnYkcHipSCin4WjjiuHeP1gIz6Z2elpYdBCE4KfpUA1UbGnxf2eFiuN+Jweln0sMrmxiX4EsoB5ClUAghYXfn4i4RBi4exLtp2SRb/Lw+wsl9T7WeKRimgadcJkC+Vh+3tHsP3QIEIKcCb7WSqG28slM6qmv5Zw5HFw2OlpEYeNjT69bzuNQQvl5WcjvnlKkqpar923Y9hGTwvLw4yb8EhIKfpv5ia9zCgQ08Pc+fkRgYedQNoIWvwuDxv/mvs5yegYek9LkfKw53KlYYunN1bMiSq5P/LY/FrKRvzgEEGLpelhFbRYEmDQQnlomubrE92c/RD1+E6zUx7GRnzjJtzPsYniJNDqvg8/ubWBuJSxx/qeFp/Lw+xlWirjDdYJYrnkYDJTMFjlqOPK5HZPiygNi4RYjhkkjdXZ14Te4dS4B7ssD6OKN5wyNqj60QxrPsl3qzTLKA8r/PcrdcRsJfJzsaQQqJ6WEXfGQ1eV8JwUz/Uqn25KjGBz/MdN3JzV89RXVxeP6DeU+UrENE3D8+xnqUji/TeZUV15HzKPO2Y5ZnCIAETTxg9oGbRQxROn6mGfNqiGTKc+bpVmWVkuWeXBQICgcGNZol2Bmh7m0huF0WdlY3qYz+VhYkmktUZ8MbWQQYugKErRsce7u4ewt2cY0bCC02ZN8vryyEV1sQhELOFGtkVkrdmEHyyxSAi1ufuTnuHifS0MWqjimXe0+HX64nZpltiqXuxGTh8IwEyLZJkWuR+PdEbFYC7Qdbo8rJTdQSNpv6eHGb1hmXFKGfq5WDIvUSJ2OM+CyWe3ZrMsy2ZOKpo5puAJhRTUxdzb1WJkWtiEHzRWxx67dYDmFwYtdAy/93EARtmWa5kWK9PDYtkfjxFmWozGch+b+YKSaTGfiDqdMSilZDEhyXJJYPwhCgMcv5pXsUyLaMJnaVhlcrMZf8BUHkbBYnXBZK8E93NOYtBCx+j3eR8HYF7s6PwLdSqjIpXJnvhaGnnMTIsre0fsEunwAcmnh4kT0dpYGJGwsy+xpTXi+1seFo+EEAllM7bjBZwDzLTkVWiC2Oh+FjbhVyJxs+nG2GPziHEKFn2C2Dhjj1keRhXPrSZiO9xcMGm+4Ss2Paza5WxPkPi5t0eoCUimxa1xx0BpmRYxPawq4k/QoiiKHoSM99ixET+/lvr8CybfODCAI4NJVEfDOLmjyYcrI7e5mWkRmc9alhUGjr6rpUimZSSVQSJXHsxMC1Uscape7+PY0WoXd6SIQCikQF/WV+wamGmRI8UclPIwt8YdA6aeFjt7WtL+locBxk3ReOOqRblKfYXsFHDK5NpspuXQmPKwZ7dmS8NOn92MGEfWViQ3F0yyPCy4xNjjYj0t4rBRUSrnIIivcnSMPn2xZGVmWob0yWHFBw3oPS0MWkw9LT6Wh8Wt3fj6zc1MpXhOBqk8DDACzoFxTov72dOSV0t9/vKw5zjquOK5mmnRf97YiB80RnlYkaDFdIAWClXGSGsGLXQMGTaoGo34zr9Qi69ZrDQMAKqjLA8TZJgeJt5YZc+0uDmtxW72T9M003JJHzMtFne1DOSeZ+xpGc2YHmYELemMihe3M2ipdCJo6XMlaMm+jjDTEjxNeiN+4Z6WXgl6UZ3GoIWOYWRaJGjEdyHLMWJhcpj5GrinRY6elqAsl3Tz30rvabH4nBT1zIC/mRarj51eHsabqFGm5BrxzT0tm7r60J9Io6EqgpPaG/26NHKZKA/rG2dKVClYHhZcek9LkUxLpTXhAwxaKA/znha/eFEeVj3OTVwpTc+Vys3mcquMvgjJgxYX/63iNjMtiZQpaPGpER8wTovHG3nMPS35Tc4FLT1DKaQy2cf02dyo47PmTEa4Qko/6FjelIfx5y1o9J6WIsEsgxaaEPRGfClGHrsYtIyTaalx8RqCRgSyjT6mmcUbayKtIp2xvhHea24G/UZ5mLW/v2jCDylANOzfja3VgJMjWPNrqo7qgcmR3ILJ59nPMiGwEZ/ysTLyWBygMWihiiZDeViNi/0kw0lr5WHm7eOaVnyTdyXTNE2KPqfRSwrlDSTdnLRmt2TR3IRfbOiE22otNOKrqqbv4OH0sNFCIQWTa42+lkQ6g5d3dgMAzp7H/SyVrIGZFsrDyshjNydZ+oVBCx2jf1im8jDnX6hFac245WGmoMbcGzDRDCYzUHMxm5+BbCwS0kdUy9zX4maAJ56zibTVoCW3o8XHfhbA2rjqoVQG4mygnuVhx9AXTA4ksG53D0ZSKlrq4ji+tc7nKyM3ideR/oTzmRbRiM+gJXiaTCOPCx2qsjyMJgQZJkV5Ux5W/IXaHNRM5BIxcRMeC4cQ93kXRG0AJoi5OTLc7p4WPdPi8+MmelSKjasWWZhISPH9eSajyfoEseSoUcd+ZtDIfW72tBjlYRx5HDQiEEmrWsH7Exn2qzmN7wx0DCnKw2L2Go7tENmbmnFOn8MhRV/YNpEXTJr3jvh9g2TsapE4aPGiPMzi81GGHS2Atelh/aZxx34/z2Q0xZRpeT7XhM9+lspn9LS4UB6WZHlYUFVFQ/r9SaFmfGZaqOKNpDJI5kqhZCgP87MRHzA1Pk/oTItYLOn/C59o6B6UeMGkFyOPLQctabGjxe/ysPH3tHCxZHFiweTu7iGs290DADiH/SwVz8i0FC4DKtUgG/EDS1EUY1dLgWZ8N3eG+YVBC40ibrgUxbhB9EN1zMVG/JT1oMWJ0cvffeh1/OLp7SV/vt/0aXISvPBZXVLoJzcnttjd02JkWnwu67MwPUyUh7EJPz+xYPKRTQeQVjXMmFSNjuYan6+K3CaCllTGWBTrhEQ6g1QmGwQxaAmm8Xa1VGJ5GJ+pNIq44aqPRxDycfa/q434YnqYhdNnuyfbY+3rHcYtT25DOKTg+rNnIRoO3jlBrwSDGQTZF0wm06r+XHEl0xKzV65o9LT4nWkZ/3HjYsniJtca5WEAS8MmitpYBIoCaFo222LlsM0Kc7a61qGvSd5qGmdXCzMtVPFkaMIHjGDB7/KwqjKDFrFTIaNq6B4sPE9dZrI8JwDTza8LwawT+ky7FNxYkGj3+SiWSzp1o1Mq8W9RNGjhYsmiRHmYcPZcloZNBKGQor/u9TnY1yJ+FquiIUQCeJhGQKO+q4U9LTRBiWY/v/sXnCjLKmRI39My/s1RdZkZH3Ogcqg/UdLX8JtUPS2SN+LrpXTxiCtbykXQMpJSoarj17eL5ZK+l4dZeNzY01KcKA8TmGmZOBpcWDA5wJ+3wNN7WoaPPRBNZVR9nxmDFqpYxuQjf1/IREAx5MJixxG9p2X8p3+5U8yOmhrkDg0ENGgZkee0xkqZkZ/cnrxnHsNtZXeQbOVhA4l0wZ9n8/QwOpaYHgYA81rr0NpQ5ePVkJfcGHvMJvzgK9bTYn6uyFDa7RQGLTSKuEH1uxlWZDgyqoZkxtnFjkO5rEl1dPwfZGMvRmnXcLQiMi1yBLKAeU+LnNPD3Bx3DIweXWwlkBaNu35PDxM3RqqGgs3ERiO+/88zGU2qNTItzLJMLA0ujD3Wd7T4OHCHytNUYyyYHEuUhtXGwhVV/lc5fxNyhCylQDWmGnynS8SM8jDrjfhDpZaHmV5MAhu0uDjC1y7ZG/GNfyt3bgTMu4NGLAUtcpSH1UTDEKtXCpWIsRG/uGg4hOZc4MKgZWIxjz12ijj4YXlYcDUWKQ+rxH4WgEELjWFeJOinaDiEaDh7l+N0M744obYStIiPsXKDmI8503I4qOVhw+6WPNkhfSO+B/9WdibaiayG38slQyHFtGMn/2PHnpbxffL8Obj0pKm4cH6r35dCHnK3PIyTw4KqqUgjfiWOOwY48pjG6JfoVL06GkYqk3Y+aEla3xJe7vSw7qEKKA9zOXtgh7HvQ9LyMA9+fqqjYfQOpyxlIPVGfJ97WoDszdFAIl0406JPD/P/tUdWn7xgrt+XQD4Q5dp9LjTis6cluMTI4948I4+ZaaEJQaZTddGM73R52LCd8rBYeaOXeyopaJHgOSF7eVivB/0/1Tayf7KUhwHjTxDTG/F5E0U0ihuZFk4PC75imRa3+yv94v87GUnFaMT3/4WsJlZeP0k+mqZhKGV95HFNtLzysO5BU09L0MvDJDgBl3562LD7mRY72b+EJOVhgNGrUuixEzdRMmT0iGTiRqaF08OCjz0tNOF5cdNllZ7lKDFgyCeZUZHJ7bewsnCvusx9MaN6WgKYaVFVzSgZlGB6WE2u/lraPS0ujzwGgOpc1sRSeViAMi1cLkmUn3jtdWV6GIOWwBKZlpGUeszBah+DFuDrX/86FEUZ9WvBggVuXRv5wLjp8v+FzI0FkyOm0cXVNnpaSikP0zRtVE9L30i65IyNXwaTaYgdhjIEskHJtLj5RlFtY3eQsVzS/0zLuOVhLFchyqveheWSg/rPm/+vDVSaOtMS47F9LZWaabH97nDSSSfhb3/7m/EFInyDqSRyZVpyCyYdDFqGUtkX6ohpdGwx5SyXHEpmkMwtAAwp2R0VhwcSmDGpxvbX8osIYmORkFQ3vtLuafFgaIFoqrfW05Lb0yJBI36xgFPTNKPGnpkWolHc6WnJvn4w0xJciqKgqTqKI4NJ9AylMNW0cFampdBOsv1sjUQimDZtmhvXQhIQL4oyPNFr9MWOzr1QiwDISmkYYGRjSsmQHM1lWWKREFpqY+jqHcGh/mAFLWLTrgxBLADU5QLZZEZFMq1aCjy95EXzY5WNDKRc5WGitO/Y6x5MZqDlMnr1cTmea0SyaHBx5DEzm8HWWCOCltF9LV4MhfGD7XeyN998E+3t7ZgzZw6uu+467N69u+jHJxIJ9PX1jfpFckqmVT2jIMNNak2Zk7vysTM5DDBuEEu5hqO5Jvzmmhim5E5AgjZBTJa9PYJ5p4CMJWK9HgwtMPa05N8sb2YELTJkWrL/JvkeN9HPEg4pUgRYRDJxpTwsdxhYa2EgDcmrSW/GnxjlYbbeHc4880zcfvvteOihh3DLLbdgx44dOO+889Df31/wc1auXInGxkb9V0dHR9kXTe4wvyDKUKJR7rjhfERQZqWfBTBle0rItIh+lkm1MUypiwMADg8cO+VDZrI180XCIcRz2RUZm/G9CPLsZP9kWS4JGLXzeYOWhDG1UFEUT6+LSHaiPKxvJA1NpCTLxHLMytBUk9vVMsSg5RiXXXYZrr32WixZsgSXXnop/vrXv6Knpwd/+MMfCn7OTTfdhN7eXv1XZ2dn2RdN7hD9C+bmLj+V009SiFEeZu2FWt+JUVKmJRugNNdGMaU++8ISvEyLPOOOBVHO4PTS0XKNpIweJlenh9nY05JIy1QelitxyRO09I+wVIWoEJFpyaiaY++HLA+rDE0Fxh6LIKbSgpaynq1NTU044YQTsHXr1oIfE4/HEY/Hy/k25BGjCV+OFzGjEd+5E3XRH2O1PKy6nExLLmiZVGNkWg4NjNj+On6ScUFVbTyCI4NJ6TItIsuiKEbvjRvs7GnRMy0SNOIXWwzKRXdEhdXGwvowl/6RtKUdY+MZZCN+RWjMs2BSVTX9cEim924nlHX8NjAwgG3btqGtrc2p6yEf9XuwY8ION3pahmz2tJRToiYa4ybVxDClPhe0BC7TIlcgCxS/+fWTeQlnyMVMpR5I22rE9z9oKbZcUrz2yLDUlkg2iqI42teiaZrR08KRx4HWVJ2t4jD3tPQn0vpgE5mqJJxgK2j54he/iFWrVmHnzp147rnncM011yAcDuMDH/iAW9dHHjJuUOV4kruxp2XY5k2cuEFMpFWoqr1a4lE9LfVB7WmRK5AFivdG+MmroQX6cslxMi3pjIp07jkrU3lYvulhAywPIyrK3NdSriHTtD7+zAWbWDBp7mkRFRJxSVYVOMnWs3XPnj34wAc+gCNHjmDKlCk499xz8cILL2DKlCluXR95SDzRZTntrC5jsWMhdqeHmUcjj6QzttLyxvSwKFrqgp5pkSdoGW9JoV+82nFktadlJG1MF5Phjct43I49KRalDPUSPc+IZJL92Rh2ZOyxOPAJKdaH0pCcRNBi7mmp1CZ8wGbQcuedd7p1HSQB46RYjie6CBCczLTYLQ8z9wIMJe0FLXpPS+3o8jBN0wIzIalPwlnvYkSnbJmWXo+CFqs9LeagJi7BPpu6IotB9UyLJAcmRLIxFkyWXx4mDnxqY5zWF3QiMDH3tFRy0OL/OxlJw6jJl+PGQe9pSbmwXDJq7e8YMu2NsBs8HTX1tIhMy3Aqg0HJpl4VI2emJVceJtm/oz5pzeUAr8piT4sIWuKRkBQ3JiIgyZch00ces1SFKC/xvizep8vBJvzKIUYe9+QpD5PlANpJDFpIJ1umxY09LeJGrjpm/alvZy+GmQhammtjqI1HUJv7+xwOUImYjD0tE748zOJySZl2tADGRLVkWkUqM/raOT2MqDgnG/H1TAub8ANPjDzuHWamhSaYfsl2crjRiD+kjzy2fnNUo49etn4dmqbpPS2TarMnIS2iRGwgQEGLhNPD6mSdHuZR0G+5p0UfOiHHy7z5BmnsY9fH8jCioozyMOd6WnhIEHyip2UgkdYPgxi00IQgW/+CmyOP7TQfVlmc1mQ2mMwgmXsBac6lb6cEsBm/V8I0s7yZluz1uP1GYTXzJ9O4YwCIhEN6b83YG6+BETbiExXjZE+LMe5Yjvd6Kl19VRSi+le8XzNooQlBnBTLcuNQ7UIjvt3pYdnrsL9g8miuCb8qGtI/P2i7WlRV0wMDmV78pN3T4lFWynojvjyLJQU9SzZmYSzLw4iKa9DLw8p/3TPKw/jzFnThkKI/N0Rfi4yHjU5h0EI683I8GdTkbs6SGRXpTPH6fauG9Z4W6zdyNVH7wZO5CV8wdrUEI2gxL6iSZQw2YOxpcTID5wSvmh+rLZZNylYeBhjlX2MDzgEulyQqShwmOrGnheVhlUXf1ZIbe6wPhanA11N53s3Id14tx7PKHFgM2WyCL6Sk8rASemv0ccemoCVou1rETXhVNIS4RKf1YuSxfOVh3jbij7fwdCSdmx4mSXkYYH7sRv8sMdNCVJyzI4/F9DB5XhuodE3V+TMtMlVIOIVBC+lka8SPR0II5Wo1nSoRM8rDrN8cWd1AbmaeHCYErTxMxnHHgMyN+N5MWjMH3CIwyUe26WGA8dgNjIxtxM8+19iIT5SfG434LA+rDI25w1H2tNCEkc6o+mmnLHWQiqKUNLmrGLHzxVZ5WAm9Nd1jJocBpkb8gJSHyTjuGDD3tMhaHubujYB5UWSx56ReHibBYklB37FjCjg1zeid4p4WovyM8jAHMi1iWp+NwzuS19hMSx+DFqp05lIbmerKjV0tzpyqDyezp8/2pofZb8Tv0XtajBeN4GZa5Hk+AHJOD9M0zbPMVCik6IFLseekbNPDAKCuyhjPKQwlM6beqcp7kyVyQoODmZYBTg+rKKKnpWeYjfg0QYhT9epoGNGwPE8Lp3e1DOt7WmxMDyshaMnb02JqxNe0wr0IspB1q665PEyWf8eRlIpUJnstXpxuWdnVkkiL8jB5fp7r8mRaRAATDilSXSuRTOpNAX+5r3tsxK8s+oLJoWT2AI2ZFqp0sjXhCyJgcKI8TNM0vaHfTtBSSuCUr6elpS7736mMNmp7raz6JOtxEmpyN75pVdNvzP0mfn7CIcXWc6tUeiCdLPz3lzHTojfimzKn4uS4Lh6BIhYOENEoogIio2plvx+yp6WyiJ6WnuEUhpIZpFXvDtC8xqCFAMjbdO3kgslEWtXLUOz0tFgdMWumZ1pMQUs8EtZfRIJQIibbslGh1lSHLUszvjE5zJsbbyvZPymDljyN+GIaEk99iQqriYURzk2mKbdEjNPDKkujqadFHIhGPDpA8xqDFgIgb9O13gSfKv/m1Bx0uN3TcjTXiN9sKg8DgtXXImsgGw4p+uMnSzO+1zXE4jlZrDzMWC4pz8t8fZ49LXoTvmS9U0QyURTFsbHHg/yZqyh6I/5watTksErMXMvzbka+Ejeosr2IVTuYaRGlYbFwCBEbfTulZHtEeVhTzeib2CBNEJM1kAXka8b3OsDTs38WMi1S7WnRHzfjurlYksga8TNS7oJJlodVFn255FBS2l5UpzBoIQDeLcazy8lGfNGEb6c0DDCyMsVOtc00Tcvb0wIYzfhByrTIWBerN3Q7NFWuXEaA581NgJXn5Ehavj0ttXl27PSzKZjIkvp49rW43EyLOOyp5cjjimCeHlbJk8MABi2UYyzGk+tFzMmelqGk/SZ8wH552EAirU+SmjS2PCxAmZZeSQNZIP/Nr5+8zrToz0kre1okmsglgk1zhkzfGSHh84xIJk5kWtIZVR9gwoOCytBYbSyXFLtaZDxsdII872bkK1kzLdVR55ZLihs8O/0sgP0SNdHPUh0NH5PVCVRPi6SN+IB8Cya9HjFppzysKiJRpiWWJ9MywkwLkRVi7HE5mRbzaybLwyqDeN/RNGDP0aFRv1dpGLQQAOPGQbaUolEeVv6JuuhpsVseVmNhJ4bZ0TyLJYUp+q6WpK1r8EO/pCOPgdG7WmTQ5/HPT3V0/OWSiZR85WF1Vcf2Ig0k5OynI5KNEwsmxbjxWDiEmERDOqh0sUgItbn7lF3dImipzNdTPmMJgLyTopxsxB8usTys2kIpjln30LHjjgWxqyVYmRa5nhOAfI34vUPGyGMv6NPDipWHpWUsDysyPYynvkRFidfi8jItoglfnsMMKl9TrhR9dy5oke1ezinyvJuRr8QNqmynnfpySRvjhgsRgU+1zebDKn3BpbUb5KOD+ZvwgeCUh2VUTW+Q9upG3I58m9X9ZCxn9SrTEuw9LYPJDNTcAjS9PEzC5xmRTOqdyLRwclhFEuVgu4+wPIwmAK/LW6xydHqYKA+zefJslIdZ276uL5asKRy0dA8mkMndtMnIvPyvXsITm3yb1f3kWyO+lT0tEmZaAGPy2wCnhxFZ4kTQMsift4okJogdyd1/MGihimbe6C0TozzMieWS2a9RYzPTIk61kxkV6cz4gUuhcccAMLk2jpACqBpwZFDebIu4Ca+OhqWse66RrafF65HHejBf+Pmo72mRqBE/HgkhktvqLRqCuaeFyBpnGvGZaalEY3fCMWihitbvcXmLVSLAcCLTYpSHlTY9DLA29vhorr9h7IsIkN3mLoKZw/3yNuP3Sjw5DDCXh0kyPczr5ZKipyUdrPIwRVGO6UcypofJ9dpDJBsnRh6Lxa4MWiqLGHssyHYv5xQGLQR1VP+CXE90J/e06I34Nm/i4pEQFCX3NawELUV6WgCgJQC7WmQdzCDI1ojv+chjS4348pWHAcc24+vlYcy0EBUlMi3i9aYURnmYPIcZVD5mWmjCGEimoeXaK2Qr0XB0eliJI48VRTHdJI5fHlaspwUIRjO+Ue4k5wufTCOPk2lVP/n0qv+napw9LaqqIZmWb+QxYEwtMjItcg4BIZKNo434NsukSW5N1QxaaIIQpzaxSEi6Gxy7O1KKKbU8DDBPMRv/zaJYTwsQkKBlRO6tuvmWFPrliS0HkVE1tNbH9cfWbeNNDxMbr80fK4s6U5ZM0zSOPCayyNjTwp4WGm1spkXWA8dyMWgh41RdwlKgmmj2hdXP8jDA3PhsvaelYKalTiyYlDhokXQwg2Aeneu3e9buBQBcvWw6wrkmc7eNtzvIHOTLdhBRa8qSDacyEEP0WB5GVJx4jxYBfyk4PawymXtaFKVyD4EYtJBpx4R8T/JqUxmMWuaI4KESp4cB1vZiAICmaXpPy6Ta/EFgIDItEi+WBOQpD+sZSuLx1w8CAK5ZNt2z71sdy750F8pAigb9aFjxLJCyyvzYiTKXkCJfRohINqL8VNVKP7BhI35lMmda6uMRhCR73XcKgxbSbxykzLSYSrmKTUqyQgQcVaWUh1ksU+tPpJHOBVeB7mmR+DkBHNsX4ZcHXt2HZEbFgmn1OLGtwbPvK8YYFwqi9R0tEo07FsTNUr8paKmLR6AolfkmS+SUqqgxMrzUEjE24lcmc9DSmGdyaaVg0EJSn6qbT1/LLRErqzwsam0ggMiy1MTCBctypgRhepj0I4+N0/pSyySccM+6bGnYu07xLssCjF+uqO9okTB7YX7s9H4WSYNjIpkoilJ2M/4Ae1oqUpOpPEzWXlQnMGghvTxMxuk9oZCij2wtd1eLCDhqysi0jHcN400OA4xMi9Q9LQEZeaxqRlbBa7uODGLNrqMIKcBVJ3sctIhpdgX+7saOFvle4o2gJcPFkkQ2lTv2mEFLZRqVaWHQQpVM5kZ8wOhBKTfT4sT0sPHKw3pEE36BfhbA2NPSM5RCosySN7fIPvK4OhrWd+f4VSImsiznzGvB1IYqT7+3eD4mMyoyeXq99PIwCTMt5h07A4nszwubgomsKTfTwkb8ylQVDSMeyd7SM2ihiiZzIz5gLs0q7+Z0pMQ9LebPGS9wspJpaayOIhrO3nEfGUjavhYvyJ5pCYUUvczPj2Z8TdN8Kw0DRj+H8wXSov9LzkyL8biJ3ilODiOyRgQtfWX2tDDTUnlEtkXW920nyPeO5pFdRwbx/UffwM2Pven3pfiuX/Ib1Bob44aL0cvDou5NDxtvRwuQveEW2RZZm/Fl72kBRp/Ye23t7qPYdWQINbEwLj1pmuffX5yoAfmfkwlRHiZxI/5AIq2Xh/HUl8gaUR5Wbk8Lf+Yqj+hrYaalAu3vHcGPHnsTv31xt6/X8ef1XXh1T4+v1yB7KVCNxSxHMaqq6Td35ZSHjRe0WMm0APJPEJN9ehjg79jju3O7Wd6+aFpJI7TLpShK0V0tMpeH1Y0qD2MjPpEdDWUELZqm6aOSGbRUHjE1TNZ7OSdM2KBl0fRGhBRgf98IDvSN+HINbx7ox2fvWIdP/2atL99fMEqB5HwR00uzxgkYijGPSy6lEd9qtsdKpgUw+lpkbMZPZ1T9ZlLmFz9jwaS3QUsincEDr+4DALxr2QxPv7dZsTHcwWjENwctcr72EMnG6GmxXx6WSBs9cLUceVxxpuV6K1tzh6KVqKx3tO985ztQFAU33nijQ5fjndp4BMe31gMA1nf2+HINWw8OAAD29gzro3L9IHv/gjjJHi7j5tQcbJRy+lxlNWgZzDXijzMnfYrE5WHmcitZA1nAvKvF22EGT7x+EL3DKUxtiGP53Mmefm+zYtk/mUce15qmh/WzPIzIloYyGvHNr+21PmSIyV1feNsJ+JfLF+CKJW1+X4prSg5aXn75Zfz0pz/FkiVLnLweTy2Z0QgAeHVPry/ff8/RYf2/txzo9+UaAHN5mJwvYlab4IsRnxuPhEraEG65PCyXaZk0TqZFLw+TMNMing+1sTAiYflO6gVxozvkcXmYKA27+uTpvm6bLzYKfCQdgOWSIyn9tJhBC5E1Rk+L/UyLKKWtiYUrdmP6RDarpRafOH+uLyXLXinpjmRgYADXXXcdfv7zn2PSpElFPzaRSKCvr2/UL1ks7WgCAKz3qaek8+iQ/t9b9vsXtEjfiG9xsWMxItgopTTM/HnjZ1py5WEB7mkxpsnJ+XwQ/GjEPzqYxBNbDgIA3nWKf6VhgJExLJZpkbE8TJS3DCZNmRaJM3pEMjGmh5WeaeHkMAqqkt7RVqxYgSuuuAIXX3zxuB+7cuVKNDY26r86OjpK+ZauWDqjCUA20+LHVm0ZMi2aphlN15LepDoxPcxYLFnai3WxG0SzoxYzLTL3tOiTwyQNYgVzmZFXHtiwD6mMhoVtDZg/rd6z75tPsd1BMjfii8cto2o4Mph9/stchkgkk/IyLWzCp2CzHbTceeedWLt2LVauXGnp42+66Sb09vbqvzo7O21fpFvmT6tHLBxC73AKu44Mjf8JDtsjQaZlKJnRG/NkbYatdmC5pAh4Sj15tlIepmkajorlkgHOtPQGYNwxYGro9rAR/+61ewD4s5tlLFE2GbRMS40pkNrfm33+18XlDpCJZFHOckljR4t8hxlEVti6K+ns7MTnPvc5PProo6iqsrYBOh6PIx6Xc5JBLBLCwvYGvNLZg/V7ejCrpdaz761pGjq7jUzLG/v7oWkaFMXbOlNRChQJGSNUZaNnWlJlNOKnRC1vaTfixjCAwkFL30haDwCbxmvElzhokX0wgyAaSb0qD9txeBDrdvcgpADvXNruyfcsRs/+JdVj/iwhlktK2NMSCimojYUxmMzomRaWhxFZU07QopeHVXDPA1U2W8dwa9aswcGDB3HKKacgEokgEolg1apV+NGPfoRIJIJMxtspPk5YmmvGX9/pbTN+92ASw6kMFCUbMPQn0ujq9X708jNvHgaQHdHrdcBklRN7WsTnlrKjJft5uabnIpkW0c9SGwuPW5YjgpbBZAZDHo/sHY/se3uEWtNmdS/csy7bgH/e8VPQ2mDt0MZNxaeHyVseBhglYqIql+UqRNaI1+W+Mhrx+fNGQWXrmXvRRRdhw4YNo37vIx/5CBYsWIAvfelLCIflfIMsZsmMJgC7PF/w2JnrZ5laX4WG6gjeODCAN/b3Y3pTtWfXcKBvBN98YDMA4PqzZ3n2fe1ycnpYqY34VUUW+QlWJ4cBIrAJYSSl4nB/EjMny/MmIvveHsHL5ZKapuGedfKUhgHj9bTIWx4GZDMrB01ZRllLU4lkI35WBhJpqKpmawoYG/Ep6Gw9c+vr67Fo0aJRv1dbW4vJkycf8/tBISaIbezqRTqjejbiVfSzzJhUjbamarxxYACv7+/HWxa0evL9NU3DTXdvQN9IGktmNOKT58/x5PuWwolGfHETV2oJnJXyMH1ymIWgRVEUTKmPo7N7GIcGRjBzck1J1+UGvRFf8kxLjYfTw1bvOorO7mHUxsK4ZOE017+fFVaWS8q4pwU49qSXJ79E1oiyXU3L9vPV2yjjFY34DFooqOQ8hvPQnJZa1McjGEmpeDO37NELYnJYR3MN5k+tAwC84eEEsbvX7sXjrx9ELBzCf167VOp9HNVR0Yhf+s1p2eVhFhrxRRN+0zhN+IKsCyb1aXKS97TU6eVh7pelit0sly1uK/k55LRi2b9hPdMix7WOZa6pDymlZ0CJJpp4JIRoOJtdsdvXIoaW1LERnwKq7HD7ySefdOAy/BMKKVg0vRHPbz+C9Z09OLGtwZPv29ltZFrmT8t+z9c9miB2oG8E/3b/JgDA5y4+HidM9Xd063ic7Gkp9eZIBC1pVUMqoyKaJ8gzdrRYu9mXtRm/LyDTw8SNr9vlYSOpDP7yahcA4F3L5CgNAyz2tETkPIwwn/TWxSPS9tMRyUZRFNRXRdE9mETfSArtsF5SzvIwCjo539E8ZiyZ9K4ZX2RaZkyqxoLcvodtBweQzhw7CchJQSoLE2qKjHa1ajhZ3vQw8+l6oeDJTk8LYOxqkS5oyfW0NEpeHubVcsknXj+IvpE02hqrcNacya5+LzuKDYcYkTzTYu5hsVPeQkSlTxBjIz4FHYMWGBPEvGzGFz0tHZNqML2pGjWxMJIZFTuPDLr6fYNUFiY40YhfbrlMNKwgnGt4zNdDAJgzLRbLw0SmZSBZ0jW5RZ8eJvnNpHjjLed5YcWfcqVhV5083VbTq9uqijTiJ9KyTw8zros3UET2GEGLvQlig8y0UMDJf8fqgSW5TMvr+/sL3pA6SdM0U6alBqGQopdouVkiFrSyMMFKE/x4yi0PUxRjj02h6ziay7Q0Wcy0SFseNhKMRvxa03JJTczOdVj3YBJPbjkIQJ6pYUKxnhbZp4eNKg/j5DAiW+pzy1jtZlpYHkZBJ+c7msfaG6vQUhdHRtWwqavP9e93aCCBRFpFSAHamrL7HubnAog3XApaglgWJhg9LaXfnA6XGbQA42d8jg5mb/YtZ1pEediAZEHLcDCWS9aZdn24lW154NUupFUNi6Y3SBfkF+9pkbs8rC5mLg/jDRSRHaLfsM92eVj2dYGN+BRUDFqQPUX3skSsszubZWlrrNYbuudPczfTEsSyMEEEC6pmlL3YpU8PK+MmbrwJYkZPi71G/MMSZVrSGRWDuX8r2Rvxq6IhiGott5rxxdSwa5bNcOXrl8N4Ph77M2E04st5c2LOrrA8jMge0QdmtzxMz7SU2NtJ5Lfg3Lm6LLtkEljf2eP69xL9LNMnGVM/RNDixtjjoJaFCTWmQKPUEjERaJQzrrbYMj/A3p4WwNSIP5BwrbzJLhE0xyIh6RukFUVxtRl/26EBvNLZg3BIwTuXtjv+9cul72kZ8zOhaRpG0sEpD2OmhcieUhvxWR5GQSfnO5oPlnaITIv7E8T0HS2TjIWCImjZ1T1U1j6SsYJcFiZEwiHEcpmhoRJ7jtwuD1NVTe9psduIn0yrttP8brnvlWxm4W0nTtUHD8hMnNK7savl3nXZf4vzj2/RHyuZ6I346dF/92RGhYiBg7BckpkWIntKzbSIjDQPCiioGLTkiEzL9sOD6B2290Jgl8i0zDBlWlrq4phcG4OmAVsdXHIZ5LIwMxEwDJcY0IlAUCyqLOkaipSH9Y+koeZuFK0ul6yKhvU3Dxma8TOqhvteye4juVqifSTFuJVpyaga7skFLdecIl9pGICCgyFGTOViQci01MXlzugRyaYh974hJj1aoaqafuDGTAsFlZzvaD5oro2hozkbRGxwOdti3tFi5nRfS9DLwszKXTDpZKZlbDkOYPSz1MUjiNlY6CfTBLHnth3Gwf4EJtVEccEJU/y+HEtqc4+J0z0tf3vtAPYcHUZDVQRvO3Gqo1/bKdUF9hclcv+vKNAzlLIxNwLz1JfInlJGHg+aDvyY3aSgkvMdzSdLRV+Ly834enlYc82o3z/BwQlilVAWZlburhYne1ryle91D9prwhdEX8thCSaIiczClUvabQVefjKPPXbSz57aDgD40FnHlfWccVOhHitzE76sm+bN2RWOPCayxygPs/66J0powyEF8YC8vhONxWeuiQha3Jwgpqoa9hbItCzIZVq2ONCMXyllYUJNLH8pjFWOTA+LFZ7WZHexpCBLpmUomcZDG/cDCE5pGOBOediaXd1Ys+soYuEQPnz2LMe+rtNE6VcqoyGVMZ6TsjfhA6OXS9bz1JfIllIa8Y3JYfIeZhCNR953NR8syY09Xt/pXnnYwf4EkhkVkZCCaQ1Vo/5MlIdtKTPT0juUqpiyMKEmWvr284yq6aOSyyoPK9LToi+WtBu0SLKr5dHNBzCUzOC4yTU4ZWaTr9dih9GI71zQIrIsVy9rR+uYn1GZmHewmLMtsu9oAcY04jPTQmRLQwmN+OI1kqVhFGQMWkwWTW9ESAH2943gYN+IK99DNOG3NVUdk/04PhdcHOxP6Cf3pXjyjYPoG0ljTktt4MvChOpY4dKs8ZiDjJoy5tMXGwagTw6zOO5YkCXTIvaRXH3y9ECdwokTe6emh+04PIhHNh8AAHz8PLl/duKREMRDNTwqaMmVh0kctNRyehhRyUrJtAxy3DFVAAYtJrXxCI5vzQYO611qxu8Uk8Oaao75s7p4RB8GUE4z/lNvHAYAXLxwauDLwoSaAk3HVphLysqp5S2WaekezJ54TSox0+JnT8uh/gSefvMQgGCVhgGmnhaHMi2/fGY7NA1464JW/RBBVoqiGH0tSVN5WO75KXPdejQc0q+PjfhE9oieloFkGqpqbccXd7RQJZD3Xc0nRolYjytff0+3aMKvzvvn80Uzfol9LZqm6Teg5x8fjAlQVpTTiD9s6mcJlbF7xMi0FOlpsdmIL0Om5f71XVA1YNnMJsxuqfXtOkpRF3OuEf/IQAJ3rd4DAPhEQDKU+QLpIJSHAcDfLz8Ob5k/BbNb6vy+FKJAEYG+pgH9Fg9sxGskM5sUZAxaxljS0QTAvQlieqZl0rGZFqD8scev7+/Hwf4EqqIhnDZrUmkXKaFyRh4PpdKjvkapjBvEPNPDhsT0sOCVh+n7SAKWZQHMjfjll4f9+oVdSKRVLJnRiDNnN5f99bxQlS9oSYvyMLlf3v+/Kxbito+cEYglpkQyqYqG9XHmVvtaxGukeQgGUdDI/a7mg5P1CWK90DRraVc7Cu1oEU4oM9MisixnzZks/UmrHaIXpZTlkvrksHKDliITzHpE0FLi9LAjg0lkLKb5nbT1YD827O1FJKTgyiXtnn//cjnViD+czOD/nt8FIJtlCUpfj747KICZFiIqnd2+Fva0UCVg0DLG/Gn1iIVD6B1OYdeRIce/fqEdLcKCaQ0AsrtaSgmaRD9LJZWGAeYdKfZP1EccGHds/vz8PS2lBS2icT+janozv5fuXdcFALhw/hTbQwRk4NTI4z+t3YPuwSRmTKrG20+a5sSleSLfc1Isl6yKMGghqlSlBi0sD6MgY9AyRiwSwont2cDB6RKxjKqhq6d4pmV2Sy0iIQX9iTS6eu1NMBtOZvDSzm4AwPkntJR3sZIpZ0+LCHScKw/L09MylE3R273xj4ZD+ud43YyvqppeGha0BnzBmB5WetCSUTX84unsmOOPnTs7UMMrjEb8fNPDgvP3ICJ76m2OPWYjPlUCvqvlcXKuGf9VhyeI7e8bQVrVEA0raK3Pv/8hFglh7pRsY+qW/X22vv4LO44gmVbR3lilf41KUV5PizPlYTUFRh6rqmaUh9lsxAdMu1ps9rWkM+qopYJ2rd51FHt7hlEfj+DiE6eW/HX85MT0sEc3H8DOI0NorI7i2tM6nLo0T1TlmarH8jCiytdQzUwLTTwMWvJYkutrcXqC2J7ubLnZ9Kbqos2nJ+hLJgdsff2n3shNDTthSmBq8q2qzvW0DJU08lg04pf3Yp3vBhEA+kZSEO0odsvDgNKa8QcTaVz4n0/ish8+jd4h6wvGzO5Zl52UddniaYG9wa2Nld+I/7OntgEAPnTWzMCdQlblxgaPbsRn0EJU6erj9jItYpdVbZmHd0R+YtCSx9KObKZlY1cv0mWcZI/VqTfh5+9nERboQYu9TIs5aKk0hbIcVgw73dMyZuSx6Gepj0cQLaG0qKUuG+jYCVoeeLULe44OY+vBAXzpT6/a7n8aSWXwwKv7AAS3NAwovxF/za5urN3dg1g4hOvPnuXglXkj33AIUR4WZ3kYUcUSPS19FjMtLA+jSsB3tTzmtNShLh7BSErFmwftZTuK2ZMbd1xoR4sgdrVsOWD9e+/tGca2Q4MIKcA5cyurnwUob0+L2+VhR0scdyyITIudnpY7X+7U//uhTfvxmxd22fqeT245iP6RNNoaq3DW7Mm2PlcmoqdlOJUp6YDhp6uyvSzXLJtesGRTZnpPS77yMDbiE1Us0dPSZyHT0jOU1CeSis8jCiIGLXmEQgoWT3d+yWRnt7VMi9jVsu3ggOWehadzWZaTO5rQWFN5L0o10dIb8Ycdb8TPjMpsdA9m3zTKDVqsZlq27O/Hut09iIQUfPrCuQCAb/7lNWzqst6DdffabAP+VSdPL2vhpt/qq6J6ucOnfrPW0hu4sP3QAB597QAA4OPnz3bl+tyWd0+L3ojPoIWoUlmdHpZMq/jkr9dgX+8I2hursHxucA+piBi0FLAkVyK23sFm/D36YsnimZbpTdWojYWRzKjYeXjQ0td+Kref5bwKG3UsiH6UkjItDu1pET0tqgYkTcHk0Vx5WHOJwaIetFjMtNzx0m4AwMUnTsU/XzofFy1oRTKt4jN3rLNUJtUzlMQTWw4CCOZCSbNYJISV716CWCSEv712AFf/5FlstZgd/eUzO6BpwEULWjGvtd7lK3WHUR5mPB+Nnha+vBNVKitBi6Zp+PLdr+LFHd2oi0fwyw+fjsbqyjvUpImD72oFGEsmexz7mnss9rSEQgqO10vExl8ymc6oeObN3H6WCuxnAczlYSX0tKSc7WkBRmd8jpa4WFKYUpctS7KSaRlJZfQxxe8/owOKouA/rl2KaQ1V2H5oEF+9b9O4X+OBV/chldGwsK1Bz+oF2TuXtuOPn1qOtsbsv8HVP3kWj24+UPRzDg8k8Mc12UEEnzh/jheX6Yqie1qYaSGqWA0WRh7f/PhW3L12L8IhBT+57hSc2Nbg1eURuYJBSwFLOpoAAK/v7x9VL16qVEbFvt7cYslxMi2AuRl//KBl/Z5e9I2k0VAVwdLcuOZKU1NgcpcVTpWHRcMhRMPKMdfRXWZPS0u92NMy/nLJhzbuR+9wCtObqvWsWnNtDD/6wDKElOySxLvX7in6Ne7NBT1Bz7KYLZnRhD/fcC7OmNWMgUQaH/+/1fjB396AquYfUPDr53chkVaxdEYjzpjd7PHVOkcELYk85WHlBulEJK/xRh7fu24vvv/oGwCAb161CBdU6IEmTSwMWgpob6xCS10MGVXDpi57U7zy2d87AlXLlrO05PZyFHPCVOtBi5gadu7xLYFajGeHCDhSGc32bhKRnakuc+QxYOohMGdaRHlYqT0tuedD92By3L+bKA279rQZo8ZmnzG7GTdefAIA4F/v3Yhth/KXSO0+MoTVu44ipADvPLm9pOuV1ZT6OH778TNx/fLjAAA/+Nub+ORv1hxzEjmczOD/nt8JAPjE+XMDPR68+J6WynwtIKLiyyVf2tGNf/7jqwCAT54/Bx88c6an10bkFr6rFaAoCpY6WCLWaepnsdL4rGdaLJSHiX6W8yu0nwUY3Y9it69FfHyNAyfP+ZZc6o34JZaHTaqJ6QHIkSLZlu2HBvDijm6EFOC9eZYgrnjLPCyfMxlDyQxu+N26vBnCe1/JZlnOmdeCqQ3Bm5Y1nmg4hH+7ahG+954liIVDeHRzts/FHMT9ce0eHB1KoaO5GpeeFMylmkK+8jDR0xJnpoWoYhXqadl+aACf+PVqJDMqLls0DV96+wI/Lo/IFQxainByyeQei5PDBLFgcnf3UNE+jt6hlH59ldrPAgCxcEi/sbc7QWzEoZHHQP4Rs6Knpbm2tAbHUEixtKvl96uzY44vOGEK2puOLTEMhxT84P0nY3JtDK/t68O3//raqD/XNE0vDbv65MopDcvnvad14A+fWo5pDVXYdmgQV//4WTz22gFkVA2/eDo75vhj584JfGayOk/mT58expHHRBXLyLQY9wfdg0l89PaX0TOUwtKOJnz/vScHejok0VjBfsd2mZgg9qoDE8T0HS0W+lkAoKUujpa6GDQNeLPIvpZntx2GqgHzWuvy3shWCkVR9EyJ3WZ8p6aHAflHzIqgpanETAsAvWTw0MBI3j9PplX8Kdc4/v4zCqf6pzZU4b/euxQA8H/P78JDG/fpf/bqnl5sPzyI6mgYb180reRrDYqTO5rw58+cg9NnTUJ/Io2P/d9qfOo3a7DryBCaaqK49rQZfl9i2UQJWN49LSwPI6pYItMykEgjo2oYSWXwif9bjZ1HhjC9qRq/+PvTHHnPI5IJ39WKEOVh2w8PonfY+v6HfDotTg4zm2+hREz0s5x3fOUtlByr1AWTwy6Xh5Xb0wKYFkz25y8Pe+y1Azg8kMSU+jjeuqC16Ne6cH4rPpmbiPXPf3wVnd3ZgFlMHbvkpKkTZitya30Vfvuxs/Chs2ZC06BPFfu7s47Tx2gHWd7yMO5pIap4ImgBsn0t//zHV7F611HUV0Vw+0dO199TiCoJg5Yimmtj+vb6DWVmW6zuaDEbrxlf0zQ9aKnk0jChusQJYnpPiwM3qeIaxGl2RtXQM1xeTwtgNOMX2tVyx8vZ0rBrT52BqIWSpi9eOh8ndzShbySNz96Z7W+5f30XAODqCpoaZkUsEsK/X70Y33nXYsTCIdRXRfD3y2f5fVmOyNeIz5HHRJUvHgkjFsm+F3zjgc348/ouREIKbv3QqfrKBKJKw6BlHHpfS5nN+GJHS0ez9UyLaMZ/o0CmZduhAXT1jiAWCeGs2ZW/5bY6WmKmRe9pKf/pPraHoHc4BS03VbepxOWSgGnBZJ6els7uITydG7bwvtOPbcDPJxoO4eYPLEN9VQTrdvfg73/5Eo4MJtFSF8N58yo/K5fP+8+Yiae/9BY8dOP5FXMKaTwfuVySaKJpyGVb7l6bzaJ/+5rFOGeCvr7TxMB3tXE4sWQykc5gf1+2V6GUTMvrBTItq97ILpQ8Y1bzhKhd1Xe12OxpGdZ7WpzItGS/hgicRD9LfVXEUgakEL2nJU/QctfqTmgacPbcyThucq3lr9nRXIPvvXsJAOClnd0AgHcsbQ9883k5pjZUYXoF9X6NHQyRUTWkMtkomo34RJVNLJgEgBVvmYv3WjzUIgqqiXv3YtGS3LLG9Z2ll4ft6xmBpmVvMCbb6HsQQcuh/gS6B4/tdRCn7+efMDFOVmrGBAxWpDMqkrndJ070tFTnTq9F9saJfhbAlGkZUx6WUTX8YfX4DfiFXLa4DR86y/i8SlooSceWTJob8lkeRlTZWnLvG1cuacM/vm2+z1dD5D5bQcstt9yCJUuWoKGhAQ0NDVi+fDkefPBBt65NCoumNyKkAPv7RnCwL/9kp/Hs0Zvwq20tsquNR/SemrF9LSOpDF7YfgTAxOhnAUprxB8y3cS5MfJYBJPl9LMA5kb80UHLqjcOYn/fCCbVREveKfKvVyzE20+ahveeNgOLpzeWdZ0kFxGYZDMs6qigJR7hmRRRJfvqlQvxr1eciP+8dilHG9OEYOtdbcaMGfjOd76DNWvWYPXq1XjrW9+Kq666Cps2bXLr+nxXG49gXmsdAGB9ic34nSU04QvzpzYAALbs7xv1+6t3HsVISkVrfRzzJ0jTnVEeZj1oGcl9rKI4cxNXqDzMsUzLmKDljpeyDfjvOmUG4iWW+1RFw7j1707F996zNNDb3+lY1aZsynAqg5F0NqsYi4R4E0NU4RZNb8THzpvDrCpNGLbu4t7xjnfg8ssvx/HHH48TTjgB3/rWt1BXV4cXXnjBreuTwtIyl0zqO1psNOEL86dlA6YtY3a1PPWmGHU8ZcLciOYbNzyeIdO4Yyf+ncaOmO0eLH9yGGD0tPQn0vpp+cG+ETz++kEAwAfOYK0yHSsaVvSlqyPJjLGjhVkWIiKqMCW/s2UyGdx5550YHBzE8uXLC35cIpFAX1/fqF9Bs6SjCUDpE8TM5WF2zZ+WP9NijDqeGP0sAFAdzWU5UtYb8YccbMLPfp3cMr/c1+0ZEuVhpU8OA7JTYMT4SpFtuWvNHmRUDacdNwnzWidGNo3sURRlVCA9wnHHRERUoWwHLRs2bEBdXR3i8Tg+9alP4Z577sHChQsLfvzKlSvR2Nio/+roCN6J8bJc0LJ211Ek0vbG7QLQl/vZWSwpiNKvNw4MQMvN1j3QN4LX9/dDUbKZlomilPKw4VyAU+PQdLWx5WF6T0uZ5WGKooza1aKqGu58eTcA62OOaWKqMg2HYNBCRESVynbQMn/+fLzyyit48cUX8elPfxrXX389Nm/eXPDjb7rpJvT29uq/Ojs7y7pgPyxsa8C0hioMJjN4btsR25+v72gpIWiZM6UW0bCCgUQae3uyX0dkWRZPbyy7lyJISmnEF/srqh26iRtbHuZUTwswuq/l+e1H0Nk9jPp4BFcsaSv7a1PlqjLtDhpJqbnfY3kYERFVFtvvbLFYDPPmzcOpp56KlStXYunSpfjhD39Y8OPj8bg+bUz8CppQSMHbFmYnNz2y6YCtzx1JZXAwV+5TSnlYNBzC3CnZvhaxZPLpN7P7Wc6fQFkWoLRMy1Bup4tTe2yO7WlxZnoYMHpXyx0vZbMsVy1r10c9E+XD8jAiIpoIyj6OU1UVicSxC/EqjQhaHt18AKqqWf48kR2pjYVL3phuXjKpqhqe2ZoLWibIqGOhZsxOCivExzpVHjY2cOoZEo345fW0AEam5Y0D/Xpw/P7T7e9moYlFBOQjKVOmhYsliYiowtg6wr3ppptw2WWXYebMmejv78fvfvc7PPnkk3j44Yfduj5pnDVnMurjERweSGBdZw9OPW6Spc/TS8Oaa0qeXjV/Wj2wHnhjfz82dvWiezCJungEy2Y2lfT1gsroJ7HfiO9U0FI1NtPiQnnYXav3IJlRsXh6IxZxrwqNwygPM/a0xFkeRkREFcbWO9vBgwfx93//95g/fz4uuugivPzyy3j44Yfxtre9za3rk0YsEsJbFrQCAB7ZvN/y5xlN+PZLw4T5pkyL6GdZPncyouGJdWNSEy2hET/pbLlMtSnTks6o6B3OZVocDFpEQPR+jjkmC0aVh6VZHkZERJXJVqbll7/8pVvXEQiXnDQVf17fhUc2HcCX377AUubEGHdsvwlfmD8tG7RsOzSg7+2YaKVhQGl7WlwrD0tl0DucQm6gG5qqHSgPy/W0ANkb0XcubS/7a1LlE0HLSCqDRFo04jNoISKiyjKxjurLdMEJUxALh7Dj8CC2HRoY/xNgLJYsJ9MyvakatbEwUhkNa3f3ZK9lgjXhA6VNDxOlZE41s1ebsj1iclhjdRQRB7JeU+qNbM2VS9pQX1V+IESVb3RPC5dLEhFRZeI7mw31VVGcPW8yAOBhi1PEOh3ItIRCCk6YZiwXnDW5BjMnl/71gkoEHnYa8Y3lks73tHQPOteEDwBT6qr0/37/GWzAJ2vMI48TnB5GREQVikGLTZcsnAYAeGSztaBlby7T0tFceqYFMPpagIlZGgaYy8OsN+KLk2fH9rSYgp99vdmA1Il+FiCbjbtiSRvee9oMnDLBhixQ6Ub3tHBPCxERVSYugLDp4oWt+P/uBdZ39mB/7wimNVYV/NihZBqHB7IlROVkWgCjrwUAzpuApWGAuQxGhapqCIXG7ylyenqYOfgR46ybHdjRAmQzaj/54CmOfC2aOESAMpzKIJMbx85MCxERVRoex9nUWl+FZR1NAIBHXyuebdmbKw2rr4qgscxGbZFpiYQULJ87uayvFVTmwMNqiZjT5WHhkIJYrl+gq8fZTAtRKcyN+FwuSURElYpBSwkuOSlXIrap+OhjfUdLmVkWADh9djPeubQdX7x0PuriEzNBZl6YZ7UZf9jhTAtg3CTu6xkB4MyOFqJSmcdwi+WScTbiExFRheE7WwkuWTgVAPD8tiP6no58Oh2YHCZEwyH86APL8KkL5pb9tYIqFFJGTe+yYtjhnhbACIBEeViTQ434RKUwD4dgpoWIiCoVg5YSzJlSh3mtdUirGp7ccrDgx+mZluaJN+nLLXozfspaM75RHuZcdkoEQE73tBCVwmjEV02N+AxaiIiosjBoKZHIthSbIubEjhYaze6ulmF9T4tzN3HihrB/JPu12dNCftIHVCTNmRa+tBMRUWXhO1uJRF/Lk68fRCKd/wa6s7v8HS00Wk3MXnmYnmlxoTxMYE8L+UlvxE+b9rREmGkhIqLKwqClREumN2JqQxyDyQye23Yk78fscWhHCxlEmZflTEvK2elh+b6WU8sliUphXi4pGvFZHkZERJWGQUuJQiEFb8uViD2ap0RsIJHG0aFsk/70JgYtTqmJ2lsw6cb0sLE3hJPY00I+0qeHpTIYSbM8jIiIKhPf2cpwycJsidijmw9AzS11E0SWpakmivoqnsQ7xU55WDKtIp17XGqizjXimwMgRUHZO3iIyiECFO5pISKiSsagpQxnzZmM+ngEh/oTeGVPz6g/29Pt3I4WMthpxDcHNo6Wh5luCBuro4iE+WNE/qnOWx7G5yQREVUWvrOVIRYJ4S0LWgEAj2waXSLm5I4WMtSYSmHGs/3wAIDsFvtoWHHsGsyn2Bx3TH6rzrOnJc5GfCIiqjAMWsp0yUli9PH+Ub/PHS3uqNEb8Yv3tGzc24uP3v4yAODM2c1QFOeCFnN5GBdLkt+qcs9HVQMS3NNCREQVikFLmS44YQpi4RC2HxrE1oMD+u9zR4s7rJSHrdl1FB/4+Qs4OpTC0hmN+J/rTnH2GsyZFo47Jp/lG+fN8jAiIqo0fGcrU31VFMvnTgYwOtti7Ghh0OKkmmjxRvzntx3B3/3yRfSPpHH6rEn4zcfORJPDJVzm/hhODiO/RcMhREKjM4nMtBARUaVh0OIAvUTM1Nei72hhI76jimVaVr1xCB++7SUMJTM4Z95k/OqjZ7gyuc0ctDDTQjIwZ1uyPVx8aSciosrCdzYHvO3EbNDySmcPDvSNoHc4hb6RbM/FdGZaHFVTYLnkI5v24+O/Wo1EWsVbF7Til9efrn+s08w3iE5ncYhKUWUKpKsifFknIqLKw3c3B7Q2VGHZzCYA2Z0tIssyuTbm2o3zRGVMDzMa8e9f34VP/3YtkhkVly+ehls/dKqr5TGje1rYiE/+Mz8nWRpGRESViEGLQ8SiyUc2H9Anh83g5DDHjS0Pu2t1Jz535zpkVA3XLJuOH71/GWIunzSzp4Vkw6CFiIgqHYMWh4i+lue3HcZr+/oAsAnfDXqmJZnBr5/fiX/646tQNeADZ3Tgv65d6smiR04PI9mYp4XFOTmMiIgqEN/dHDJ3Sh3mTqlFKqPhjpd2A2DQ4gYRtGw9OICv3LcJAPCRc2bh29csRijk3C6WYkZlWhi0kATM2ZUqLpYkIqIKxKDFQZeclC0RO9CXAMDJYW6ojmZ7hNKqBgD4hwvn4qtXLnR0eeR4algeRpIxB9Lc0UJERJWI724OumTh1FH/z0yL8yaZGt+/eMkJ+Oe3L/A0YAGA6txwhZACNFazEZ/8x54WIiKqdBxt5aClM5rQWh/Hwf5cpoWN+I5ra6zGN686CZNqY7hySbsv19DeWIX3njYD0xqqEPaoJI2oGAYtRERU6Ri0OCgUUvC2hVPx2xezPS3Tm5hpccPfLZ/l6/dXFAXfe89SX6+ByMy8p6WaQQsREVUgloc57NJcX0t7YxVPPInIE+ZAhdPDiIioEjHT4rDzjm/B196xEMe31vt9KUQ0QbA8jIiIKh2DFocpioKPnDPb78sgoglk1PQwjjwmIqIKxDoCIqKAG7WnheVhRERUgfjuRkQUcOZAheVhRERUiRi0EBEFXDUzLUREVOH47kZEFHBsxCciokrHoIWIKOCq2IhPREQVjkELEVHAcU8LERFVOlvvbitXrsTpp5+O+vp6tLa24uqrr8aWLVvcujYiIrKA5WFERFTpbAUtq1atwooVK/DCCy/g0UcfRSqVwiWXXILBwUG3ro+IiMYxak8LgxYiIqpAtpZLPvTQQ6P+//bbb0drayvWrFmD888/P+/nJBIJJBIJ/f/7+vpKuEwiIipkVKYlwvIwIiKqPGW9u/X29gIAmpubC37MypUr0djYqP/q6Ogo51sSEdEYVSwPIyKiCldy0KKqKm688Uacc845WLRoUcGPu+mmm9Db26v/6uzsLPVbEhFRHiwPIyKiSmerPMxsxYoV2LhxI5555pmiHxePxxGPx0v9NkRENA5zSRiXSxIRUSUq6d3thhtuwAMPPIAnnngCM2bMcPqaiIjIhkg4hJa6OGLhECbVxvy+HCIiIsfZyrRomobPfOYzuOeee/Dkk09i9uzZbl0XERHZ8NuPnYmBRBoNVVG/L4WIiMhxtoKWFStW4He/+x3uu+8+1NfXY//+/QCAxsZGVFdXu3KBREQ0vvnT6v2+BCIiItcomqZplj9YUfL+/m233YYPf/jDlr5GX18fGhsb0dvbi4aGBqvfmoiIiIiIKozV2MB2eRgREREREZGXOGaGiIiIiIikxqCFiIiIiIikxqCFiIiIiIikxqCFiIiIiIikxqCFiIiIiIikxqCFiIiIiIikxqCFiIiIiIikxqCFiIiIiIikxqCFiIiIiIikxqCFiIiIiIikFvH6G2qaBgDo6+vz+lsTEREREZFEREwgYoRCPA9a+vv7AQAdHR1ef2siIiIiIpJQf38/GhsbC/65oo0X1jhMVVV0dXWhvr4eiqJ4+a2P0dfXh46ODnR2dqKhocHXayHr+LgFEx+3YOLjFkx83IKJj1sw8XErj6Zp6O/vR3t7O0Khwp0rnmdaQqEQZsyY4fW3LaqhoYFPsgDi4xZMfNyCiY9bMPFxCyY+bsHEx610xTIsAhvxiYiIiIhIagxaiIiIiIhIahM6aInH4/ja176GeDzu96WQDXzcgomPWzDxcQsmPm7BxMctmPi4ecPzRnwiIiIiIiI7JnSmhYiIiIiI5MeghYiIiIiIpMaghYiIiIiIpMaghYiIiIiIpMaghYiIiIiIpDZhg5af/OQnmDVrFqqqqnDmmWfipZde8vuSaIynnnoK73jHO9De3g5FUXDvvfeO+nNN0/DVr34VbW1tqK6uxsUXX4w333zTn4slAMDKlStx+umno76+Hq2trbj66quxZcuWUR8zMjKCFStWYPLkyairq8O73/1uHDhwwKcrJgC45ZZbsGTJEn2b8/Lly/Hggw/qf87HLBi+853vQFEU3Hjjjfrv8bGT09e//nUoijLq14IFC/Q/5+Mmr7179+JDH/oQJk+ejOrqaixevBirV6/W/5z3Ju6ZkEHL73//e3zhC1/A1772NaxduxZLly7FpZdeioMHD/p9aWQyODiIpUuX4ic/+UneP//e976HH/3oR7j11lvx4osvora2FpdeeilGRkY8vlISVq1ahRUrVuCFF17Ao48+ilQqhUsuuQSDg4P6x3z+85/H/fffj7vuugurVq1CV1cX3vWud/l41TRjxgx85zvfwZo1a7B69Wq89a1vxVVXXYVNmzYB4GMWBC+//DJ++tOfYsmSJaN+n4+dvE466STs27dP//XMM8/of8bHTU5Hjx7FOeecg2g0igcffBCbN2/Gf/3Xf2HSpEn6x/DexEXaBHTGGWdoK1as0P8/k8lo7e3t2sqVK328KioGgHbPPffo/6+qqjZt2jTtP/7jP/Tf6+np0eLxuHbHHXf4cIWUz8GDBzUA2qpVqzRNyz5G0WhUu+uuu/SPee211zQA2vPPP+/XZVIekyZN0n7xi1/wMQuA/v5+7fjjj9ceffRR7YILLtA+97nPaZrGnzeZfe1rX9OWLl2a98/4uMnrS1/6knbuuecW/HPem7hrwmVakskk1qxZg4svvlj/vVAohIsvvhjPP/+8j1dGduzYsQP79+8f9Tg2NjbizDPP5OMokd7eXgBAc3MzAGDNmjVIpVKjHrcFCxZg5syZfNwkkclkcOedd2JwcBDLly/nYxYAK1aswBVXXDHqMQL48ya7N998E+3t7ZgzZw6uu+467N69GwAfN5n9+c9/xmmnnYZrr70Wra2tWLZsGX7+85/rf857E3dNuKDl8OHDyGQymDp16qjfnzp1Kvbv3+/TVZFd4rHi4ygvVVVx44034pxzzsGiRYsAZB+3WCyGpqamUR/Lx81/GzZsQF1dHeLxOD71qU/hnnvuwcKFC/mYSe7OO+/E2rVrsXLlymP+jI+dvM4880zcfvvteOihh3DLLbdgx44dOO+889Df38/HTWLbt2/HLbfcguOPPx4PP/wwPv3pT+Ozn/0sfvWrXwHgvYnbIn5fABFVphUrVmDjxo2j6rRJXvPnz8crr7yC3t5e/PGPf8T111+PVatW+X1ZVERnZyc+97nP4dFHH0VVVZXfl0M2XHbZZfp/L1myBGeeeSaOO+44/OEPf0B1dbWPV0bFqKqK0047Dd/+9rcBAMuWLcPGjRtx66234vrrr/f56irfhMu0tLS0IBwOHzOF48CBA5g2bZpPV0V2iceKj6OcbrjhBjzwwAN44oknMGPGDP33p02bhmQyiZ6enlEfz8fNf7FYDPPmzcOpp56KlStXYunSpfjhD3/Ix0xia9aswcGDB3HKKacgEokgEolg1apV+NGPfoRIJIKpU6fysQuIpqYmnHDCCdi6dSt/5iTW1taGhQsXjvq9E088US/t472JuyZc0BKLxXDqqafiscce039PVVU89thjWL58uY9XRnbMnj0b06ZNG/U49vX14cUXX+Tj6CNN03DDDTfgnnvuweOPP47Zs2eP+vNTTz0V0Wh01OO2ZcsW7N69m4+bZFRVRSKR4GMmsYsuuggbNmzAK6+8ov867bTTcN111+n/zccuGAYGBrBt2za0tbXxZ05i55xzzjFj/N944w0cd9xxAHhv4jq/JwH44c4779Ti8bh2++23a5s3b9Y+8YlPaE1NTdr+/fv9vjQy6e/v19atW6etW7dOA6B9//vf19atW6ft2rVL0zRN+853vqM1NTVp9913n/bqq69qV111lTZ79mxteHjY5yufuD796U9rjY2N2pNPPqnt27dP/zU0NKR/zKc+9Slt5syZ2uOPP66tXr1aW758ubZ8+XIfr5q+/OUva6tWrdJ27Nihvfrqq9qXv/xlTVEU7ZFHHtE0jY9ZkJinh2kaHztZ/eM//qP25JNPajt27NCeffZZ7eKLL9ZaWlq0gwcPaprGx01WL730khaJRLRvfetb2ptvvqn99re/1WpqarTf/OY3+sfw3sQ9EzJo0TRNu/nmm7WZM2dqsVhMO+OMM7QXXnjB70uiMZ544gkNwDG/rr/+ek3TsqMFv/KVr2hTp07V4vG4dtFFF2lbtmzx96InuHyPFwDttttu0z9meHhY+4d/+Adt0qRJWk1NjXbNNddo+/bt8++iSfvoRz+qHXfccVosFtOmTJmiXXTRRXrAoml8zIJkbNDCx05O73vf+7S2tjYtFotp06dP1973vvdpW7du1f+cj5u87r//fm3RokVaPB7XFixYoP3sZz8b9ee8N3GPomma5k+Oh4iIiIiIaHwTrqeFiIiIiIiChUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJjUELERERERFJLeL3BRBR6VRVRVdXF+rr66Eoit+XQ0RU8TRNQ39/P9rb2xEK8eyXyCsMWogCrKurCx0dHX5fBhHRhNPZ2YkZM2b4fRlEEwaDFqIAq6+vBwCci8sRQdTnqyEics89b2zw+xIAAH0DKo47Zaf++ktE3mDQQhRgoiQsgigiCoMWIqpcDfVylWKxJJfIW3K9AhAREREREY3BoIWIiIiIiKTGoIWIiIiIiKTGoIWIiIiIiKTGoIWIiIiIiKTGoIWIiIiIiKTGoIWIiIiIiKTGoIWIiIiIiKTGoIWIiIiIiKTGoIWIiIiIiKTGoIWIiIiIiKTGoIVIAj/5yU8wa9YsVFVV4cwzz8RLL73k9yURERERSYNBC5HPfv/73+MLX/gCvva1r2Ht2rVYunQpLr30Uhw8eNDvSyMiIiKSAoMWIp99//vfx8c//nF85CMfwcKFC3HrrbeipqYG//u//+v3pRERERFJgUELkY+SySTWrFmDiy++WP+9UCiEiy++GM8///wxH59IJNDX1zfqFxEREVGlY9BC5KPDhw8jk8lg6tSpo35/6tSp2L9//zEfv3LlSjQ2Nuq/Ojo6vLpUIiIiIt8waCEKkJtuugm9vb36r87OTr8viYiIiMh1Eb8vgGgia2lpQTgcxoEDB0b9/oEDBzBt2rRjPj4ejyMej3t1eURERERSYKaFyEexWAynnnoqHnvsMf33VFXFY489huXLl/t4ZURERETyYKaFyGdf+MIXcP311+O0007DGWecgR/84AcYHBzERz7yEb8vjYiIiEgKDFqIfPa+970Phw4dwle/+lXs378fJ598Mh566KFjmvOJiIiIJipF0zTN74sgotL09fWhsbERF+IqRJSo35dDROSah7te8fsSAAB9/SomnbAdvb29aGho8PtyiCYM9rQQEREREZHUGLQQEREREZHUGLQQEREREZHUGLQQEREREZHUGLQQEREREZHUGLQQEREREZHUGLQQEREREZHUGLQQEREREZHUGLQQEREREZHUGLQQEREREZHUIn5fABGV7543NqChnmcQZpe2n+z3JRCRg2T5mU5rKQDb/b4MogmHdzlERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCQ1Bi1ERERERCS1iN8XQETlu+aExYgoUb8vQyoPd73i9yXoLm0/2e9LICIiCjRmWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoiIiIiISGoMWoh8tHLlSpx++umor69Ha2srrr76amzZssXvyyIiIiKSCoMWIh+tWrUKK1aswAsvvIBHH30UqVQKl1xyCQYHB/2+NCIiIiJpRPy+AKKJ7KGHHhr1/7fffjtaW1uxZs0anH/++T5dFREREZFcGLQQSaS3txcA0NzcnPfPE4kEEomE/v99fX2eXBcRERGRn1geRiQJVVVx44034pxzzsGiRYvyfszKlSvR2Nio/+ro6PD4KomIiIi8x6CFSBIrVqzAxo0bceeddxb8mJtuugm9vb36r87OTg+vkIiIiMgfLA8jksANN9yABx54AE899RRmzJhR8OPi8Tji8biHV0ZERETkPwYtRD7SNA2f+cxncM899+DJJ5/E7Nmz/b4kIiIiIukwaCHy0YoVK/C73/0O9913H+rr67F//34AQGNjI6qrq32+OiIiIiI5sKeFyEe33HILent7ceGFF6KtrU3/9fvf/97vSyMiIiKSBjMtRD7SNM3vSyAiIiKSHjMtREREREQkNQYtREREREQkNQYtREREREQkNQYtREREREQkNQYtREREREQkNQYtREREREQkNQYtREREREQkNQYtREREREQkNQYtREREREQkNQYtREREREQktYjfF0BE5IZL20/2+xKIiIjIIcy0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1Bi0EBERERGR1Bi0EP3/7d1/aJZ138fhz5w5R0wxS2u0akRgqaU2kxxEkSShURBFMcEMImplJkQzsAjTZb8YtbKUCCGthJAiiAgjzVKcmlH0wyKoVdQKwlnBqm3PPw97GO1+7pvo9vvR6zjg+sOTU3lzsokvv7s2AABSEy0AAEBqogUAAEhNtAAAAKmJFgAAIDXRAgAApCZaAACA1EQLAACQmmgBAABSEy0AAEBqogUAAEhNtAAAAKmJFgAAIDXRAgAApCZaAACA1EQLAACQmmgBAABSEy0AAEBqogUAAEhNtAAAAKmJFgAAIDXRAgAApCZaAACA1EQLAACQmmgBAABSEy0AAEBqogUAAEhNtAAAAKmJFgAAIDXRAgAApCZaAACA1EQLAACQmmgBAABSEy0AAEBqogUAAEhNtAAAAKmJFgAAIDXRAgAApCZaAACA1EQLAACQmmiBJB588MGoqqqKZcuWlZ4CAJCKaIEEurq64plnnolzzz239BQAgHRECxT2yy+/REtLS2zYsCEmTJhQeg4AQDqiBQprbW2NBQsWxLx58/7tvX19fdHb2zvsBQBwrBtdegBUshdffDH2798fXV1d/9H97e3tcf/99/+X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iI8XqGxOWgAAgNRECwAAkJpoAQAAUhMtAABAaqIFAABITbQAAACpiRYAACA10QIAAKQmWgAAgNRECwAAkJpoAQAAUhMtAABAaqIFAABITbQAAACpiRYAACA10QIAAKQmWgAAgNRECwAAkJpoAQAAUhMtAABAaqIFAABITbQAAACpiRYAACA10QIAAKQmWgAAgNRECwAAkJpoAQAAUhMtAABAaqIFAABITbQAAACpiRYAACA10QIAAKQmWgAAgNRGlx4A/H2Dg4MREfFn/BExWHgMcMzpPTxQesKQPwf/KD0hIv7379v4v79/gSOjatBnHRy1vvnmm2hoaCg9A6DidHd3x6mnnlp6BlQM0QJHsYGBgfjuu++irq4uqqqq/vaf09vbGw0NDdHd3R3jxo37Bxce3TyXkXkuI/NcRnasPZfBwcE4fPhw1NfXx6hRvsoejhRfHgZHsVGjRv2j/9M3bty4Y+IfFf80z2VknsvIPJeRHUvPZfz48aUnQMXxXwQAAEBqogUAAEhNtABRU1MT9913X9TU1JSekornMjLPZWSey8g8F+Cf4I34AABAak5aAACA1EQLAACQmmgBAABSEy0AAEBqogUAAEhNtECFe/LJJ+OMM86IsWPHxpw5c2LPnj2lJxXV3t4es2fPjrq6upg0aVJcddVV8dlnn5Welc6DDz4YVVVVsWzZstJTivv2229j0aJFMXHixKitrY3p06fH3r17S88qqr+/P1auXBmNjY1RW1sbZ555ZqxatSp8w1Lg7xItUMFeeumlWL58edx3332xf//+OO+882L+/PnR09NTelox27dvj9bW1ti9e3e8+eab8ccff8Rll10Wv/76a+lpaXR1dcUzzzwT5557bukpxf3888/R3Nwcxx13XLz++uvx8ccfx6OPPhoTJkwoPa2otWvXxrp166KzszM++eSTWLt2bTz00EPxxBNPlJ4GHKX8nBaoYHPmzInZs2dHZ2dnREQMDAxEQ0ND3H777dHW1lZ4XQ4//vhjTJo0KbZv3x4XXXRR6TnF/fLLLzFr1qx46qmn4oEHHogZM2ZER0dH6VnFtLW1xbvvvhvvvPNO6SmpLFy4MCZPnhzPPvvs0LWrr746amtr4/nnny+4DDhaOWmBCvX777/Hvn37Yt68eUPXRo0aFfPmzYtdu3YVXJbLoUOHIiLihBNOKLwkh9bW1liwYMGwj5tK9uqrr0ZTU1Ncc801MWnSpJg5c2Zs2LCh9Kzi5s6dG9u2bYuDBw9GRMQHH3wQO3fujMsvv7zwMuBoNbr0AKCMn376Kfr7+2Py5MnDrk+ePDk+/fTTQqtyGRgYiGXLlkVzc3NMmzat9JziXnzxxdi/f390dXWVnpLGl19+GevWrYvly5fHPffcE11dXbF06dIYM2ZMLF68uPS8Ytra2qK3tzemTJkS1dXV0d/fH6tXr46WlpbS04CjlGgB+BdaW1vjo48+ip07d5aeUlx3d3fccccd8eabb8bYsWNLz0ljYGAgmpqaYs2aNRERMXPmzPjoo4/i6aefruho2bJlS2zatCk2b94cU6dOjQMHDsSyZcuivr6+op8L8PeJFqhQJ554YlRXV8cPP/ww7PoPP/wQJ598cqFVedx2223x2muvxY4dO+LUU08tPae4ffv2RU9PT8yaNWvoWn9/f+zYsSM6Ozujr68vqqurCy4s45RTTolzzjln2LWzzz47Xn755UKLcrjrrruira0trrvuuoiImD59enz11VfR3t4uWoC/xXtaoEKNGTMmzj///Ni2bdvQtYGBgdi2bVtceOGFBZeVNTg4GLfddlts3bo13nrrrWhsbCw9KYVLL700Pvzwwzhw4MDQq6mpKVpaWuLAgQMVGSwREc3NzX/5ltgHDx6M008/vdCiHH777bcYNWr4PzGqq6tjYGCg0CLgaOekBSrY8uXLY/HixdHU1BQXXHBBdHR0xK+//hpLliwpPa2Y1tbW2Lx5c7zyyitRV1cX33//fUREjB8/PmprawuvK6euru4v7+s5/vjjY+LEiRX9fp8777wz5s6dG2vWrIlrr7029uzZE+vXr4/169eXnlbUFVdcEatXr47TTjstpk6dGu+//3489thjceONN5aeBhylfMtjqHCdnZ3x8MMPx/fffx8zZsyIxx9/PObMmVN6VjFVVVUjXn/uuefihhtuOLJjkrv44osr/lseR0S89tprsWLFivj888+jsbExli9fHjfddFPpWUUdPnw4Vq5cGVu3bo2enp6or6+P66+/Pu69994YM2ZM6XnAUUi0AAAAqXlPCwAAkJpoAQAAUhMtAABAaqIFAABITbQAAACpiRYAACA10QIAAKQmWgAAgNRECwAAkJpoAQAAUhMtAABAav8DgTSELs+hi4AAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 1000x1000 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig,ax = plt.subplots(2,1)\n",
    "fig.set_size_inches(10,10)\n",
    "ax[0].plot(np.array(losses).mean(axis=0))\n",
    "ax[1].imshow(grid)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.13"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "import magent2\n",
    "#from magent2.environments import battle_v4\n",
    "import math\n",
    "from scipy.spatial.distance import cityblock #A\n",
    "map_size = 30\n",
    "env = magent2.GridWorld(\"battle\", map_size=map_size) #B\n",
    "#env = battle_v4.env(render_mode='human')\n",
    "env.set_render_dir(\"MAgent/build/render\") #C\n",
    "team1, team2 = env.get_handles() #D"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.14"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "hid_layer = 25\n",
    "in_size = 359\n",
    "act_space = 21\n",
    "layers = [(in_size,hid_layer),(hid_layer,act_space)]\n",
    "params = gen_params(2,in_size*hid_layer+hid_layer*act_space) #A\n",
    "map_size = 30\n",
    "width = height = map_size\n",
    "n1 = n2 = 16 #B\n",
    "gap = 1 #C\n",
    "epochs = 100\n",
    "replay_size = 70\n",
    "batch_size = 25\n",
    "\n",
    "\n",
    "side1 = int(math.sqrt(n1)) * 2\n",
    "pos1 = []\n",
    "for x in range(width//2 - gap - side1, width//2 - gap - side1 + side1, 2): #D\n",
    "    for y in range((height - side1)//2, (height - side1)//2 + side1, 2):\n",
    "        pos1.append([x, y, 0])\n",
    "\n",
    "side2 = int(math.sqrt(n2)) * 2\n",
    "pos2 = []\n",
    "for x in range(width//2 + gap, width//2 + gap + side2, 2): #E\n",
    "    for y in range((height - side2)//2, (height - side2)//2 + side2, 2):\n",
    "        pos2.append([x, y, 0])\n",
    "        \n",
    "env.reset()\n",
    "env.add_agents(team1, method=\"custom\", pos=pos1) #F\n",
    "env.add_agents(team2, method=\"custom\", pos=pos2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7f7261cbf400>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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evh1HZ/Pp3Hjxsnn82ndunWqrKxUVlaWMjIy9Pzzz6u4uPgbvQMOADB6RBWg3bt3S5IWLlwYsX/v3r1au3atJOl3v/udxowZo5UrV6q3t1elpaX6/e9/H5NhAQDJ475+Dige+DkgAEhsw/JzQAAADBUBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABNRBai6ulpz585Venq6cnJytGzZMjU2NkasWbhwoTweT8S2cePGmA4NAEh8UQWovr5eFRUVOnXqlI4fP66+vj4tXrxYPT09EevWr1+v9vb28LZz586YDg0ASHwp0Sw+duxYxMf79u1TTk6Ozp49qwULFoT3jx8/Xn6/PzYTAgCS0n29BhQMBiVJWVlZEfvfeecdZWdna+bMmaqqqtKNGzcGfYze3l6FQqGIDQCQ/KJ6BvRl/f392rJli+bPn6+ZM2eG9z/zzDOaMmWKAoGALly4oJdeekmNjY167733Bnyc6upq7dixY6hjAAASlMc554byiZs2bdJf/vIXffTRR5o0adKg606cOKFFixapqalJ06ZNu+t4b2+vent7wx+HQiHl5+droZYqxZM6lNEAAIZuuz7VqUbBYFAZGRmDrhvSM6DNmzfr6NGjOnny5NfGR5KKiookadAAeb1eeb3eoYwBAEhgUQXIOafnn39ehw8fVl1dnQoKCu75OefPn5ck5eXlDWlAAEByiipAFRUV2r9/v2pqapSenq6Ojg5Jks/n07hx49Tc3Kz9+/frxz/+sSZMmKALFy5o69atWrBggWbPnh2XCwAAJKaoXgPyeDwD7t+7d6/Wrl2r1tZW/fSnP9XFixfV09Oj/Px8LV++XK+88srXfh/wy0KhkHw+H68BAUCCistrQPdqVX5+vurr66N5SADAKMXvggMAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJlKsB/gq55wk6bb6JGc8DAAgarfVJ+l//z0fzIgLUHd3tyTpI/2f8SQAgPvR3d0tn8836HGPu1eihll/f7/a2tqUnp4uj8cTcSwUCik/P1+tra3KyMgwmnB4jcZrlkbndY/Ga5a47mS8buecuru7FQgENGbM4K/0jLhnQGPGjNGkSZO+dk1GRkbS3bB7GY3XLI3O6x6N1yxx3cnm6575fIE3IQAATBAgAICJhAqQ1+vV9u3b5fV6rUcZNqPxmqXRed2j8Zolrnu0XfeXjbg3IQAARoeEegYEAEgeBAgAYIIAAQBMECAAgImECdCuXbv0ne98Rw888ICKior0j3/8w3qkuHrttdfk8XgithkzZliPFVMnT57UkiVLFAgE5PF4dOTIkYjjzjlt27ZNeXl5GjdunEpKSnTp0iWbYWPoXte9du3au+59WVmZzbAxUl1drblz5yo9PV05OTlatmyZGhsbI9bcvHlTFRUVmjBhgh566CGtXLlSnZ2dRhPHxje57oULF951vzdu3Gg08fBKiAC9++67qqys1Pbt2/Xxxx+rsLBQpaWlunr1qvVocfXYY4+pvb09vH300UfWI8VUT0+PCgsLtWvXrgGP79y5U2+99Zb27Nmj06dP68EHH1Rpaalu3rw5zJPG1r2uW5LKysoi7v2BAweGccLYq6+vV0VFhU6dOqXjx4+rr69PixcvVk9PT3jN1q1b9f777+vQoUOqr69XW1ubVqxYYTj1/fsm1y1J69evj7jfO3fuNJp4mLkEMG/ePFdRURH++M6dOy4QCLjq6mrDqeJr+/btrrCw0HqMYSPJHT58OPxxf3+/8/v97vXXXw/v6+rqcl6v1x04cMBgwvj46nU759yaNWvc0qVLTeYZLlevXnWSXH19vXPuv/c2NTXVHTp0KLzmX//6l5PkGhoarMaMua9et3PO/ehHP3I///nP7YYyNOKfAd26dUtnz55VSUlJeN+YMWNUUlKihoYGw8ni79KlSwoEApo6daqeffZZXb582XqkYdPS0qKOjo6I++7z+VRUVJT0912S6urqlJOTo+nTp2vTpk26du2a9UgxFQwGJUlZWVmSpLNnz6qvry/ifs+YMUOTJ09Oqvv91ev+wjvvvKPs7GzNnDlTVVVVunHjhsV4w27E/TLSr/rss890584d5ebmRuzPzc3VJ598YjRV/BUVFWnfvn2aPn262tvbtWPHDj355JO6ePGi0tPTrceLu46ODkka8L5/cSxZlZWVacWKFSooKFBzc7NefvlllZeXq6GhQWPHjrUe77719/dry5Ytmj9/vmbOnCnpv/c7LS1NmZmZEWuT6X4PdN2S9Mwzz2jKlCkKBAK6cOGCXnrpJTU2Nuq9994znHZ4jPgAjVbl5eXhP8+ePVtFRUWaMmWK/vznP2vdunWGkyHeVq9eHf7zrFmzNHv2bE2bNk11dXVatGiR4WSxUVFRoYsXLybda5r3Mth1b9iwIfznWbNmKS8vT4sWLVJzc7OmTZs23GMOqxH/Lbjs7GyNHTv2rnfDdHZ2yu/3G001/DIzM/Xoo4+qqanJepRh8cW9He33XZKmTp2q7OzspLj3mzdv1tGjR/Xhhx9G/LMrfr9ft27dUldXV8T6ZLnfg133QIqKiiQpKe73vYz4AKWlpWnOnDmqra0N7+vv71dtba2Ki4sNJxte169fV3Nzs/Ly8qxHGRYFBQXy+/0R9z0UCun06dOj6r5L0pUrV3Tt2rWEvvfOOW3evFmHDx/WiRMnVFBQEHF8zpw5Sk1NjbjfjY2Nunz5ckLf73td90DOnz8vSQl9v78x63dBfBMHDx50Xq/X7du3z/3zn/90GzZscJmZma6jo8N6tLj5xS9+4erq6lxLS4v729/+5kpKSlx2dra7evWq9Wgx093d7c6dO+fOnTvnJLk33njDnTt3zv3nP/9xzjn329/+1mVmZrqamhp34cIFt3TpUldQUOA+//xz48nvz9ddd3d3t3vhhRdcQ0ODa2lpcR988IH7/ve/7x555BF38+ZN69GHbNOmTc7n87m6ujrX3t4e3m7cuBFes3HjRjd58mR34sQJd+bMGVdcXOyKi4sNp75/97rupqYm96tf/cqdOXPGtbS0uJqaGjd16lS3YMEC48mHR0IEyDnn3n77bTd58mSXlpbm5s2b506dOmU9UlytWrXK5eXlubS0NPftb3/brVq1yjU1NVmPFVMffvihk3TXtmbNGufcf9+K/eqrr7rc3Fzn9XrdokWLXGNjo+3QMfB1133jxg23ePFiN3HiRJeamuqmTJni1q9fn/D/szXQ9Upye/fuDa/5/PPP3c9+9jP3rW99y40fP94tX77ctbe32w0dA/e67suXL7sFCxa4rKws5/V63cMPP+x++ctfumAwaDv4MOGfYwAAmBjxrwEBAJITAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGDi/wFxBIjJjq1QswAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(env.get_global_minimap(30,30)[:,:,:].sum(axis=2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.15"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_neighbors(j,pos_list,r=6): #A\n",
    "    neighbors = []\n",
    "    pos_j = pos_list[j]\n",
    "    for i,pos in enumerate(pos_list):\n",
    "        if i == j:\n",
    "            continue\n",
    "        dist = cityblock(pos,pos_j)\n",
    "        if dist < r:\n",
    "            neighbors.append(i)\n",
    "    return neighbors\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 4, 6, 7, 8, 9, 10, 13]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_neighbors(5,env.get_pos(team1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.16"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_onehot(a,l=21): #A\n",
    "    x = torch.zeros(21)\n",
    "    x[a] = 1\n",
    "    return x\n",
    "\n",
    "def get_scalar(v): #B\n",
    "    return torch.argmax(v)\n",
    "\n",
    "def get_mean_field(j,pos_list,act_list,r=7,l=21): #C\n",
    "    neighbors = get_neighbors(j,pos_list,r=r) #D\n",
    "    mean_field = torch.zeros(l)\n",
    "    for k in neighbors:\n",
    "        act_ = act_list[k]\n",
    "        act = get_onehot(act_)\n",
    "        mean_field += act\n",
    "    tot = mean_field.sum()\n",
    "    mean_field = mean_field / tot if tot > 0 else mean_field #E\n",
    "    return mean_field"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.17"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "def infer_acts(obs,param,layers,pos_list,acts,act_space=21,num_iter=5,temp=0.5):\n",
    "    N = acts.shape[0] #A\n",
    "    mean_fields = torch.zeros(N,act_space)\n",
    "    acts_ = acts.clone() #B\n",
    "    qvals = torch.zeros(N,act_space)\n",
    "\n",
    "    for i in range(num_iter): #C\n",
    "        for j in range(N): #D\n",
    "            mean_fields[j] = get_mean_field(j,pos_list,acts_)\n",
    "\n",
    "        for j in range(N): #E\n",
    "            state = torch.cat((obs[j].flatten(),mean_fields[j]))\n",
    "            qs = qfunc(state.detach(),param,layers=layers)\n",
    "            qvals[j,:] = qs[:]\n",
    "            acts_[j] = softmax_policy(qs.detach(),temp=temp)\n",
    "    return acts_, mean_fields, qvals\n",
    "\n",
    "def init_mean_field(N,act_space=21):\n",
    "    mean_fields = torch.abs(torch.rand(N,act_space))\n",
    "    for i in range(mean_fields.shape[0]):\n",
    "        mean_fields[i] = mean_fields[i] / mean_fields[i].sum()\n",
    "    return mean_fields"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.18"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train(batch_size,replay,param,layers,J=64,gamma=0.5,lr=0.001):\n",
    "    ids = np.random.randint(low=0,high=len(replay),size=batch_size)\n",
    "    exps = [replay[idx] for idx in ids]\n",
    "    losses = []\n",
    "    jobs = torch.stack([ex[0] for ex in exps]).detach() #stack\n",
    "    jacts = torch.stack([ex[1] for ex in exps]).detach()\n",
    "    jrewards = torch.stack([ex[2] for ex in exps]).detach()\n",
    "    jmeans = torch.stack([ex[3] for ex in exps]).detach()\n",
    "    vs = torch.stack([ex[4] for ex in exps]).detach()\n",
    "    qs = []\n",
    "    for h in range(batch_size):\n",
    "        state = torch.cat((jobs[h].flatten(),jmeans[h]))\n",
    "        qs.append(qfunc(state.detach(),param,layers=layers))\n",
    "    qvals = torch.stack(qs)\n",
    "    target = qvals.clone().detach()\n",
    "    target[:,jacts] = jrewards + gamma * torch.max(vs,dim=1)[0] #20 = 20 + 20\n",
    "    loss = torch.sum(torch.pow(qvals - target.detach(),2))\n",
    "    losses.append(loss.detach().item())\n",
    "    loss.backward()\n",
    "    #SGD\n",
    "    with torch.no_grad():\n",
    "        param = param - lr * param.grad\n",
    "    param.requires_grad = True\n",
    "    return np.array(losses).mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.19"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "N1 = env.get_num(team1) #A\n",
    "N2 = env.get_num(team2)\n",
    "step_ct = 0\n",
    "acts_1 = torch.randint(low=0,high=act_space,size=(N1,)) #B\n",
    "acts_2 = torch.randint(low=0,high=act_space,size=(N2,))\n",
    "\n",
    "replay1 = deque(maxlen=replay_size) #C\n",
    "replay2 = deque(maxlen=replay_size)\n",
    "\n",
    "qnext1 = torch.zeros(N1) #D\n",
    "qnext2 = torch.zeros(N2)\n",
    "\n",
    "act_means1 = init_mean_field(N1,act_space)  #E\n",
    "act_means2 = init_mean_field(N2,act_space)\n",
    "\n",
    "rewards1 = torch.zeros(N1) #F\n",
    "rewards2 = torch.zeros(N2)\n",
    "\n",
    "losses1 = []\n",
    "losses2 = []"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "def team_step(team,param,acts,layers):\n",
    "    obs = env.get_observation(team) #A\n",
    "    ids = env.get_agent_id(team) #B\n",
    "    obs_small = torch.from_numpy(obs[0][:,:,:,[1,4]]) #C\n",
    "    agent_pos = env.get_pos(team) #D \n",
    "    acts, act_means, qvals = infer_acts(obs_small,\\\n",
    "                                       param,layers,agent_pos,acts) #E\n",
    "    return acts, act_means, qvals, obs_small, ids\n",
    "\n",
    "def add_to_replay(replay,obs_small, acts,rewards,act_means,qnext): #F\n",
    "    for j in range(rewards.shape[0]): #G\n",
    "        exp = (obs_small[j], acts[j],rewards[j],act_means[j],qnext[j])\n",
    "        replay.append(exp)\n",
    "        \n",
    "    return replay"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Listing 9.21"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(epochs):\n",
    "    done = False\n",
    "    while not done: #A\n",
    "        acts_1, act_means1, qvals1, obs_small_1, ids_1 = \\\n",
    "            team_step(team1,params[0],acts_1,layers) #B\n",
    "        env.set_action(team1, acts_1.detach().numpy().astype(np.int32)) #C\n",
    "\n",
    "        acts_2, act_means2, qvals2, obs_small_2, ids_2 = \\\n",
    "            team_step(team2,params[0],acts_2,layers)\n",
    "        env.set_action(team2, acts_2.detach().numpy().astype(np.int32))\n",
    "\n",
    "        done = env.step() #D\n",
    "\n",
    "        _, _, qnext1, _, ids_1 = team_step(team1,params[0],acts_1,layers) #E\n",
    "        _, _, qnext2, _, ids_2 = team_step(team2,params[0],acts_2,layers)\n",
    "\n",
    "        env.render() #F\n",
    "\n",
    "        rewards1 = torch.from_numpy(env.get_reward(team1)).float() #G\n",
    "        rewards2 = torch.from_numpy(env.get_reward(team2)).float()\n",
    "        #\n",
    "        #\n",
    "        #\n",
    "        replay1 = add_to_replay(replay1, obs_small_1, acts_1,rewards1,act_means1,qnext1) #A\n",
    "        replay2 = add_to_replay(replay2, obs_small_2, acts_2,rewards2,act_means2,qnext2)     \n",
    "        shuffle(replay1) #B\n",
    "        shuffle(replay2)\n",
    "        \n",
    "        ids_1_ = list(zip(np.arange(ids_1.shape[0]),ids_1)) #C\n",
    "        ids_2_ = list(zip(np.arange(ids_2.shape[0]),ids_2))\n",
    "        \n",
    "        env.clear_dead() #D\n",
    "        \n",
    "        ids_1  = env.get_agent_id(team1) #E\n",
    "        ids_2  = env.get_agent_id(team2)\n",
    "        \n",
    "        ids_1_ = [i for (i,j) in ids_1_ if j in ids_1] #F\n",
    "        ids_2_ = [i for (i,j) in ids_2_ if j in ids_2]\n",
    "        \n",
    "        acts_1 = acts_1[ids_1_] #G\n",
    "        acts_2 = acts_2[ids_2_]\n",
    "        \n",
    "        step_ct += 1\n",
    "        if step_ct > 250:\n",
    "            break\n",
    "            \n",
    "        if len(replay1) > batch_size and len(replay2) > batch_size: #H\n",
    "            loss1 = train(batch_size,replay1,params[0],layers=layers,J=N1)\n",
    "            loss2 = train(batch_size,replay2,params[1],layers=layers,J=N1)\n",
    "            losses1.append(loss1)\n",
    "            losses2.append(loss2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
